clerk-sdk 0.4.13__tar.gz → 0.4.15__tar.gz

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.
Files changed (69) hide show
  1. {clerk_sdk-0.4.13/clerk_sdk.egg-info → clerk_sdk-0.4.15}/PKG-INFO +1 -1
  2. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/__init__.py +1 -1
  3. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/base.py +2 -2
  4. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/client.py +10 -1
  5. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/client_actor/client_actor.py +18 -2
  6. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/decorators/gui_automation.py +23 -7
  7. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15/clerk_sdk.egg-info}/PKG-INFO +1 -1
  8. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/setup.py +1 -1
  9. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/LICENSE +0 -0
  10. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/MANIFEST.in +0 -0
  11. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/README.md +0 -0
  12. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/client.py +0 -0
  13. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/decorator/__init__.py +0 -0
  14. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/decorator/models.py +0 -0
  15. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/decorator/task_decorator.py +0 -0
  16. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/exceptions/__init__.py +0 -0
  17. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/exceptions/exceptions.py +0 -0
  18. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/exceptions/remote_device.py +0 -0
  19. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/__init__.py +0 -0
  20. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/action_model/__init__.py +0 -0
  21. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/action_model/model.py +0 -0
  22. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/action_model/utils.py +0 -0
  23. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/client_actor/__init__.py +0 -0
  24. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/client_actor/exception.py +0 -0
  25. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/client_actor/model.py +0 -0
  26. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/decorators/__init__.py +0 -0
  27. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/exceptions/__init__.py +0 -0
  28. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/exceptions/agent_manager.py +0 -0
  29. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/exceptions/modality/__init__.py +0 -0
  30. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/exceptions/modality/exc.py +0 -0
  31. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/exceptions/websocket.py +0 -0
  32. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/requirements.txt +0 -0
  33. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/ui_actions/__init__.py +0 -0
  34. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/ui_actions/actions.py +0 -0
  35. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/ui_actions/base.py +0 -0
  36. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/ui_actions/support.py +0 -0
  37. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/ui_state_inspector/__init__.py +0 -0
  38. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/ui_state_inspector/gui_vision.py +0 -0
  39. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/ui_state_inspector/models.py +0 -0
  40. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/ui_state_machine/__init__.py +0 -0
  41. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/ui_state_machine/ai_recovery.py +0 -0
  42. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/ui_state_machine/decorators.py +0 -0
  43. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/ui_state_machine/exceptions.py +0 -0
  44. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/gui_automation/ui_state_machine/state_machine.py +0 -0
  45. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/models/__init__.py +0 -0
  46. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/models/document.py +0 -0
  47. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/models/document_statuses.py +0 -0
  48. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/models/file.py +0 -0
  49. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/models/remote_device.py +0 -0
  50. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/models/response_model.py +0 -0
  51. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/models/ui_operator.py +0 -0
  52. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/utils/__init__.py +0 -0
  53. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/utils/logger.py +0 -0
  54. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk/utils/save_artifact.py +0 -0
  55. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk_sdk.egg-info/SOURCES.txt +0 -0
  56. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk_sdk.egg-info/dependency_links.txt +0 -0
  57. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk_sdk.egg-info/requires.txt +0 -0
  58. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/clerk_sdk.egg-info/top_level.txt +0 -0
  59. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/pyproject.toml +0 -0
  60. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/requirements.txt +0 -0
  61. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/setup.cfg +0 -0
  62. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/tests/test_base.py +0 -0
  63. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/tests/test_client.py +0 -0
  64. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/tests/test_document_models.py +0 -0
  65. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/tests/test_exceptions.py +0 -0
  66. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/tests/test_file_models.py +0 -0
  67. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/tests/test_gui_automation.py +0 -0
  68. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/tests/test_task_decorator.py +0 -0
  69. {clerk_sdk-0.4.13 → clerk_sdk-0.4.15}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clerk-sdk
3
- Version: 0.4.13
3
+ Version: 0.4.15
4
4
  Summary: Library for interacting with Clerk
5
5
  Home-page: https://github.com/F-ONE-Group/clerk_pypi
6
6
  Author: F-ONE Group
@@ -1,4 +1,4 @@
1
1
  from .client import Clerk
2
2
 
3
3
 
4
- __version__ = "0.4.13"
4
+ __version__ = "0.4.14"
@@ -50,7 +50,7 @@ class BaseClerk(BaseModel):
50
50
  headers: Dict[str, str] = {},
51
51
  json: Dict[str, Any] = {},
52
52
  params: Dict[str, Any] = {},
53
- ) -> StandardResponse[Dict[str, Any]]:
53
+ ) -> StandardResponse[Any]:
54
54
 
55
55
  merged_headers = {**self.headers, **headers}
56
56
  url = f"{self.base_url}{endpoint}"
@@ -66,7 +66,7 @@ class BaseClerk(BaseModel):
66
66
 
67
67
  @backoff.on_exception(
68
68
  backoff.expo,
69
- (requests.exceptions.RequestException,),
69
+ Exception,
70
70
  max_tries=3,
71
71
  jitter=None,
72
72
  giveup=giveup_handler,
@@ -40,9 +40,18 @@ class RPAClerk(BaseClerk):
40
40
  json={"id": remote_device.id, "name": remote_device.name, "run_id": run_id},
41
41
  )
42
42
 
43
+ def get_wss_token(self) -> str:
44
+ endpoint = "/wss_token"
45
+ res = self.get_request(endpoint=endpoint)
46
+ return res.data[0]
47
+
43
48
  def get_coordinates(self, payload: Dict[str, Any]) -> Coords:
44
49
  endpoint = "/action_model/get_coordinates"
45
- res = self.post_request(endpoint=endpoint, json=payload)
50
+ try:
51
+ res = self.post_request(endpoint=endpoint, json=payload)
52
+ except Exception as e:
53
+ # We always want to be raising RuntimeError here to be caught in the do() method
54
+ raise RuntimeError(f"Failed to get coordinates: {str(e)}") from e
46
55
  if res.data[0] is None: # type: ignore
47
56
  raise RuntimeError("No coordinates found in the response.")
48
57
  return Coords.model_validate(res.data[0])
@@ -1,12 +1,14 @@
1
1
  import asyncio
2
2
  import json
3
3
  import os
4
+ import backoff
4
5
  from typing import Any, Dict, Union
5
6
 
7
+
6
8
  import pydantic
7
9
  import requests
8
10
 
9
-
11
+ from websockets import WebSocketException
10
12
  from .model import (
11
13
  ExecutePayload,
12
14
  DeleteFilesExecutePayload,
@@ -15,12 +17,24 @@ from .model import (
15
17
  WindowExecutePayload,
16
18
  GetFileExecutePayload,
17
19
  )
18
- import backoff
19
20
 
20
21
  from .model import PerformActionResponse, ActionStates
21
22
  from .exception import PerformActionException, GetScreenError
22
23
 
23
24
 
25
+ async def before_retry(details: Any):
26
+ from ..decorators.gui_automation import reconnect_ws
27
+
28
+ await reconnect_ws()
29
+
30
+
31
+ @backoff.on_exception(
32
+ backoff.constant,
33
+ WebSocketException,
34
+ interval=1,
35
+ max_tries=5,
36
+ on_backoff=before_retry,
37
+ )
24
38
  async def _perform_action_ws(payload: Dict[str, Any]) -> PerformActionResponse:
25
39
  """Perform an action over a WebSocket connection.
26
40
 
@@ -48,6 +62,8 @@ async def _perform_action_ws(payload: Dict[str, Any]) -> PerformActionResponse:
48
62
  return PerformActionResponse(**json.loads(action_info))
49
63
  else:
50
64
  raise RuntimeError("Received ACK != OK")
65
+ except WebSocketException as e:
66
+ raise e
51
67
  except asyncio.TimeoutError:
52
68
  raise RuntimeError("The ack message did not arrive.")
53
69
  else:
@@ -32,6 +32,28 @@ REMOTE_DEVICE_ALLOCATION_MAX_TRIES = int(
32
32
  )
33
33
 
34
34
 
35
+ async def connect_to_ws(uri: str) -> ClientConnection:
36
+ # Same knobs as before, just via the new connect()
37
+ return await connect(uri, max_size=2**23, ping_timeout=3600)
38
+
39
+
40
+ async def close_ws_connection(ws_conn: ClientConnection):
41
+ await ws_conn.close()
42
+
43
+
44
+ async def reconnect_ws():
45
+ global global_ws
46
+
47
+ remote_device_name = os.getenv("REMOTE_DEVICE_NAME")
48
+ if not remote_device_name:
49
+ raise RuntimeError(
50
+ "REMOTE_DEVICE_NAME environmental variable is required for reconnecting WebSocket."
51
+ )
52
+ wss_token = clerk_client.get_wss_token()
53
+ uri = f"{wss_uri}/{remote_device_name}/publisher?token={wss_token}"
54
+ global_ws = await connect_to_ws(uri)
55
+
56
+
35
57
  def _allocate_remote_device(
36
58
  clerk_client: RPAClerk, group_name: str, run_id: str
37
59
  ) -> RemoteDevice:
@@ -83,17 +105,11 @@ def gui_automation(
83
105
  if not group_name:
84
106
  raise ValueError("REMOTE_DEVICE_GROUP environmental variable is required.")
85
107
 
86
- async def connect_to_ws(uri: str) -> ClientConnection:
87
- # Same knobs as before, just via the new connect()
88
- return await connect(uri, max_size=2**23, ping_timeout=3600)
89
-
90
- async def close_ws_connection(ws_conn: ClientConnection):
91
- await ws_conn.close()
92
-
93
108
  def decorator(func: Callable):
94
109
  @functools.wraps(func)
95
110
  def wrapper(payload: ClerkCodePayload, *args, **kwargs):
96
111
  global global_ws
112
+
97
113
  force_deallocate = False
98
114
  os.environ["_document_id"] = payload.document.id
99
115
  os.environ["_run_id"] = payload.run_id
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clerk-sdk
3
- Version: 0.4.13
3
+ Version: 0.4.15
4
4
  Summary: Library for interacting with Clerk
5
5
  Home-page: https://github.com/F-ONE-Group/clerk_pypi
6
6
  Author: F-ONE Group
@@ -13,7 +13,7 @@ gui_requirements = get_requirements("./clerk/gui_automation")
13
13
 
14
14
  setup(
15
15
  name="clerk-sdk",
16
- version="0.4.13",
16
+ version="0.4.15",
17
17
  description="Library for interacting with Clerk",
18
18
  long_description=open("README.md").read(),
19
19
  long_description_content_type="text/markdown",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes