clerk-sdk 0.4.9__py3-none-any.whl → 0.4.11__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.
clerk/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  from .client import Clerk
2
2
 
3
3
 
4
- __version__ = "0.4.6"
4
+ __version__ = "0.4.11"
@@ -42,9 +42,9 @@ async def _perform_action_ws(payload: Dict[str, Any]) -> PerformActionResponse:
42
42
 
43
43
  # 2. wait for ack message
44
44
  try:
45
- ack = await asyncio.wait_for(global_ws.recv(), 90)
45
+ ack = await asyncio.wait_for(global_ws.recv(), 10)
46
46
  if ack == "OK":
47
- action_info = await asyncio.wait_for(global_ws.recv(), 90)
47
+ action_info = await asyncio.wait_for(global_ws.recv(), 10)
48
48
  return PerformActionResponse(**json.loads(action_info))
49
49
  else:
50
50
  raise RuntimeError("Received ACK != OK")
@@ -24,7 +24,7 @@ from ..client_actor.model import (
24
24
  from ..client_actor.exception import GetScreenError
25
25
  from ..exceptions.modality.exc import ModalityNotKnownError
26
26
 
27
- MAX_TIME = 5
27
+ MAX_TRIES = 3
28
28
 
29
29
 
30
30
  class File(BaseModel):
@@ -80,7 +80,7 @@ class LeftClick(BaseAction):
80
80
  @backoff.on_exception(
81
81
  backoff.expo,
82
82
  (RuntimeError, GetScreenError),
83
- max_time=MAX_TIME,
83
+ max_tries=MAX_TRIES,
84
84
  on_giveup=maybe_engage_operator_ui_action,
85
85
  raise_on_giveup=False, # Exception might be raised in the giveup handler instead
86
86
  )
@@ -123,7 +123,7 @@ class RightClick(BaseAction):
123
123
  @backoff.on_exception(
124
124
  backoff.expo,
125
125
  (RuntimeError, GetScreenError),
126
- max_time=MAX_TIME,
126
+ max_tries=MAX_TRIES,
127
127
  on_giveup=maybe_engage_operator_ui_action,
128
128
  raise_on_giveup=False, # Exception might be raised in the giveup handler instead
129
129
  )
@@ -166,7 +166,7 @@ class MiddleClickAction(BaseAction):
166
166
  @backoff.on_exception(
167
167
  backoff.expo,
168
168
  (RuntimeError, GetScreenError),
169
- max_time=MAX_TIME,
169
+ max_tries=MAX_TRIES,
170
170
  on_giveup=maybe_engage_operator_ui_action,
171
171
  raise_on_giveup=False, # Exception might be raised in the giveup handler instead
172
172
  )
@@ -209,7 +209,7 @@ class DoubleClick(BaseAction):
209
209
  @backoff.on_exception(
210
210
  backoff.expo,
211
211
  (RuntimeError, GetScreenError),
212
- max_time=MAX_TIME,
212
+ max_tries=MAX_TRIES,
213
213
  on_giveup=maybe_engage_operator_ui_action,
214
214
  raise_on_giveup=False, # Exception might be raised in the giveup handler instead
215
215
  )
@@ -256,7 +256,7 @@ class Scroll(BaseAction):
256
256
  @backoff.on_exception(
257
257
  backoff.expo,
258
258
  (RuntimeError, GetScreenError),
259
- max_time=MAX_TIME,
259
+ max_tries=MAX_TRIES,
260
260
  on_giveup=maybe_engage_operator_ui_action,
261
261
  raise_on_giveup=False, # Exception might be raised in the giveup handler instead
262
262
  )
@@ -306,6 +306,13 @@ class SendKeys(BaseAction):
306
306
  )
307
307
  return self
308
308
 
309
+ @backoff.on_exception(
310
+ backoff.expo,
311
+ (RuntimeError, GetScreenError),
312
+ max_tries=MAX_TRIES,
313
+ on_giveup=maybe_engage_operator_ui_action,
314
+ raise_on_giveup=False, # Exception might be raised in the giveup handler instead
315
+ )
309
316
  def do(self):
310
317
  payload: Screenshot
311
318
  try:
@@ -356,6 +363,13 @@ class PressKeys(BaseAction):
356
363
  action_type: ActionTypes = "press_keys"
357
364
  keys: str
358
365
 
366
+ @backoff.on_exception(
367
+ backoff.expo,
368
+ (RuntimeError, GetScreenError),
369
+ max_tries=MAX_TRIES,
370
+ on_giveup=maybe_engage_operator_ui_action,
371
+ raise_on_giveup=False, # Exception might be raised in the giveup handler instead
372
+ )
359
373
  def do(self):
360
374
  # provide widget + screen to the action model via http request
361
375
  execute_payload = ExecutePayload(
@@ -484,6 +498,13 @@ class ForceCloseApplication(BaseAction):
484
498
  description="Process name from task manager. Example: process.exe"
485
499
  )
486
500
 
501
+ @backoff.on_exception(
502
+ backoff.expo,
503
+ (RuntimeError, GetScreenError),
504
+ max_tries=MAX_TRIES,
505
+ on_giveup=maybe_engage_operator_ui_action,
506
+ raise_on_giveup=False, # Exception might be raised in the giveup handler instead
507
+ )
487
508
  def do(self):
488
509
  payload = ApplicationExecutePayload(
489
510
  action_type=self.action_type,
@@ -531,6 +552,13 @@ class SaveFiles(BaseAction):
531
552
  files_details.append(file)
532
553
  return files_details
533
554
 
555
+ @backoff.on_exception(
556
+ backoff.expo,
557
+ (RuntimeError, GetScreenError),
558
+ max_tries=MAX_TRIES,
559
+ on_giveup=maybe_engage_operator_ui_action,
560
+ raise_on_giveup=False, # Exception might be raised in the giveup handler instead
561
+ )
534
562
  def do(self):
535
563
  payload = SaveFilesExecutePayload(
536
564
  action_type=self.action_type,
@@ -558,6 +586,13 @@ class DeleteFiles(BaseAction):
558
586
  action_type: ActionTypes = "delete_files"
559
587
  files_location: List[str]
560
588
 
589
+ @backoff.on_exception(
590
+ backoff.expo,
591
+ (RuntimeError, GetScreenError),
592
+ max_tries=MAX_TRIES,
593
+ on_giveup=maybe_engage_operator_ui_action,
594
+ raise_on_giveup=False, # Exception might be raised in the giveup handler instead
595
+ )
561
596
  def do(self):
562
597
  payload = DeleteFilesExecutePayload(
563
598
  action_type=self.action_type, files_location=self.files_location
@@ -714,7 +749,7 @@ class GetText(BaseAction):
714
749
  @backoff.on_exception(
715
750
  backoff.expo,
716
751
  (RuntimeError, GetScreenError),
717
- max_time=MAX_TIME,
752
+ max_tries=MAX_TRIES,
718
753
  on_giveup=maybe_engage_operator_ui_action,
719
754
  raise_on_giveup=False, # Exception might be raised in the giveup handler instead
720
755
  )
@@ -759,7 +794,7 @@ class PasteText(BaseAction):
759
794
  @backoff.on_exception(
760
795
  backoff.expo,
761
796
  (RuntimeError, GetScreenError),
762
- max_time=MAX_TIME,
797
+ max_tries=MAX_TRIES,
763
798
  on_giveup=maybe_engage_operator_ui_action,
764
799
  raise_on_giveup=False, # Exception might be raised in the giveup handler instead
765
800
  )
@@ -161,7 +161,9 @@ class ActionString(BaseModel):
161
161
 
162
162
  Attributes:
163
163
  action_string (str): The string representation of the action.
164
- comment (str, optional): An optional comment or description for the action.
164
+ action_comment (str, optional): An optional comment about the action.
165
+ observation (str, optional): An optional observation related to the action.
166
+ interrupt_process (bool, optional): A flag indicating whether the action should interrupt the process.
165
167
 
166
168
  Methods:
167
169
  ensure_format(v: str) -> str:
@@ -170,7 +172,9 @@ class ActionString(BaseModel):
170
172
  """
171
173
 
172
174
  action_string: str
173
- comment: Optional[str] = None
175
+ action_comment: Optional[str] = None
176
+ observation: Optional[str] = None
177
+ interrupt_process: Optional[bool] = False
174
178
 
175
179
  @field_validator("action_string", mode="before")
176
180
  @classmethod
@@ -180,3 +184,11 @@ class ActionString(BaseModel):
180
184
  if not v.endswith(".do()") and not v.startswith("NoAction"):
181
185
  raise ValueError("Action string must end with '.do()'")
182
186
  return v
187
+
188
+ @field_validator("interrupt_process", mode="before")
189
+ def convert_to_bool(cls, v: str | bool | None):
190
+ if v is None:
191
+ return False
192
+ elif isinstance(v, str):
193
+ return v.lower() in ["true", "1", "yes"]
194
+ return v
@@ -2,9 +2,8 @@ from typing import Union, List, Optional, Type
2
2
  from pydantic import BaseModel, Field
3
3
 
4
4
  from clerk.gui_automation.client import CourseCorrectorClerk
5
-
6
- from ..client_actor.client_actor import get_screen
7
- from .models import ActionString
5
+ from clerk.gui_automation.client_actor.client_actor import get_screen
6
+ from clerk.gui_automation.ui_state_inspector.models import ActionString
8
7
 
9
8
 
10
9
  class CourseCorrector(BaseModel):
@@ -8,9 +8,18 @@ from typing import List, Tuple, Callable, Optional, Deque, Literal, Union
8
8
  import traceback
9
9
  from datetime import datetime
10
10
 
11
- from ..ui_actions.actions import ForceCloseApplication
12
- from ..ui_actions.support import save_screenshot
13
- from .exceptions import (
11
+ from clerk.client import Clerk
12
+ from clerk.utils import logger
13
+ from clerk.gui_automation.client_actor.exception import PerformActionException
14
+ from clerk.gui_automation.ui_actions.actions import ForceCloseApplication
15
+ from clerk.gui_automation.ui_actions.support import save_screenshot
16
+ from clerk.gui_automation.ui_state_inspector.gui_vision import Vision
17
+ from clerk.gui_automation.ui_state_inspector.models import ActionString
18
+ from clerk.gui_automation.ui_state_machine.ai_recovery import (
19
+ CourseCorrector,
20
+ course_corrector_v1,
21
+ )
22
+ from clerk.gui_automation.ui_state_machine.exceptions import (
14
23
  BusinessException,
15
24
  ScreenPilotException,
16
25
  UnplannedTransitionsError,
@@ -21,12 +30,6 @@ from .exceptions import (
21
30
  CourseCorrectionImpossible,
22
31
  SuccessfulCompletion,
23
32
  )
24
- from ..ui_state_machine.models import ActionString
25
- from .ai_recovery import CourseCorrector, course_corrector_v1
26
- from ..client_actor.exception import PerformActionException
27
- from ..ui_state_inspector.gui_vision import Vision
28
- from ...client import Clerk
29
- from ...utils import logger
30
33
 
31
34
 
32
35
  class ScreenPilot:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clerk-sdk
3
- Version: 0.4.9
3
+ Version: 0.4.11
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
- clerk/__init__.py,sha256=ubAUuMPlxiWOVmwL7aMXdRDmiXjmyqibfKLX5ZcLZR4,50
1
+ clerk/__init__.py,sha256=-JHAzWtOyJr_JOTN5rh2mXi9sFVo3gAoaL_kzY7_KKA,51
2
2
  clerk/base.py,sha256=S1RKc2pBw2FPlVjefJzsNtyTDPB0UG46C2K_QVV1opA,4008
3
3
  clerk/client.py,sha256=RdOvC23WK9ZtIXDOYaoSFk9debh3UTmstBXjAswAH6E,4981
4
4
  clerk/decorator/__init__.py,sha256=yGGcS17VsZ7cZ-hVGCm3I3vGDJMiJIAqmDGzriIi0DI,65
@@ -13,7 +13,7 @@ clerk/gui_automation/action_model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
13
13
  clerk/gui_automation/action_model/model.py,sha256=yzaCyEMOH3YMkPBf6IwUMuu69-xyf78HzmthiewgWQY,3811
14
14
  clerk/gui_automation/action_model/utils.py,sha256=xzFxgN-bTK6HKGS7J-esQZ-ePj_yG72T-2ZVhcWvKjw,798
15
15
  clerk/gui_automation/client_actor/__init__.py,sha256=SVuL6-oo1Xc0oJkjMKrO6mJwpPGjrCLKhDV6r2Abtf8,66
16
- clerk/gui_automation/client_actor/client_actor.py,sha256=RT5WnvrM37pLpoDd_WZg8sSjBuugqMW_eDLTEkL7kWc,5117
16
+ clerk/gui_automation/client_actor/client_actor.py,sha256=GFUwUR0QsvuFjRulzETIXLPxBGOX255L1XUUSG15WAY,5117
17
17
  clerk/gui_automation/client_actor/exception.py,sha256=zdnImHZ88yf52Xq3aMHivEU3aJg-r2c-r8x8XZnI3ic,407
18
18
  clerk/gui_automation/client_actor/model.py,sha256=wVpFCi1w2kh4kAV8oNx489vf_SLUQnqhc02rFD5NIJA,6335
19
19
  clerk/gui_automation/decorators/__init__.py,sha256=OCgXStEumscgT-RyVy5OKS7ml1w9y-lEnjCVnxuRnQs,43
@@ -24,18 +24,17 @@ clerk/gui_automation/exceptions/websocket.py,sha256=-MdwSwlf1hbnu55aDgk3L1znkTZ6
24
24
  clerk/gui_automation/exceptions/modality/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  clerk/gui_automation/exceptions/modality/exc.py,sha256=P-dMuCTyVZYD3pbGpCf_1SYEgaETn13c51pmfbsXr5k,1436
26
26
  clerk/gui_automation/ui_actions/__init__.py,sha256=-EDQ5375HXrvG3sfFY7zOPC405YcBL6xXRACm2p-YyI,23
27
- clerk/gui_automation/ui_actions/actions.py,sha256=hhxl5VMDNSXdqm2L0tZqs6IhJHVXtlSVSdwsiz2BbDI,27449
27
+ clerk/gui_automation/ui_actions/actions.py,sha256=r_gVnAOGfv7XZyli8b8ru0nsMqn_JiTAMTNvgVf8T1I,28789
28
28
  clerk/gui_automation/ui_actions/base.py,sha256=oaUI3vIOoDwP_HdLu2GIG46-aMv0_Zv-PljMgSFeNmk,7329
29
29
  clerk/gui_automation/ui_actions/support.py,sha256=Ulb8DBfwnrBMaYoMLDgldEy9V--NDUSdhIYXpuODZoU,5772
30
30
  clerk/gui_automation/ui_state_inspector/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
31
  clerk/gui_automation/ui_state_inspector/gui_vision.py,sha256=Pk5nuFZnp_zNbqSOtndSmgqb6PLeADJfnC-eRIJMDZk,7736
32
- clerk/gui_automation/ui_state_inspector/models.py,sha256=cXFKmdTPt3m78NQ7sqGllJU0gLSfZuXd0cM0GFuD490,5542
32
+ clerk/gui_automation/ui_state_inspector/models.py,sha256=qEbdrWGglOJH8QaOKoYp8ZKQMjnGk4JufpgYuTWoQ10,6082
33
33
  clerk/gui_automation/ui_state_machine/__init__.py,sha256=bTPZsPJkDLCwP2mdtBj4fU7C7ekOh0b-VPRKFEV3bPo,301
34
- clerk/gui_automation/ui_state_machine/ai_recovery.py,sha256=3_Gu_RPxta4eXmXWH3WA31c15sJL-dk1m1H2bOFV7so,3772
34
+ clerk/gui_automation/ui_state_machine/ai_recovery.py,sha256=jAx8DehN5ue3zIroZwOADf_QyiTzFPij_5N57pJg6Us,3829
35
35
  clerk/gui_automation/ui_state_machine/decorators.py,sha256=gBOpIusjsXlA7FEiszDCFKTS6vXx3LBNMz_SQJNkMWg,2134
36
36
  clerk/gui_automation/ui_state_machine/exceptions.py,sha256=9KWg20dnCssMdMu632E0nP5vkndgYNI4cDCDW-vMkQA,1436
37
- clerk/gui_automation/ui_state_machine/models.py,sha256=oNmfHtjqgRkUAxPnQ8R5-IR-K_FCeg3NU6aqjVSnThI,1407
38
- clerk/gui_automation/ui_state_machine/state_machine.py,sha256=u2wJqu5WxmZHkzlIHTgK_icZUw3yv9nNuZkh9IaqmXI,35622
37
+ clerk/gui_automation/ui_state_machine/state_machine.py,sha256=BNBQpxutWldR8hBBnVZ1u1xhwf5MWT2vL5d12bxzsUU,35812
39
38
  clerk/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
39
  clerk/models/document.py,sha256=SdHLuX01yQ1std-o25Wso5sq7HQznV7-SN8azVzyczQ,3036
41
40
  clerk/models/document_statuses.py,sha256=67EMwh7FUNEOkb563mO5WtckK1EICY-sk9pRhD-BYK4,347
@@ -46,8 +45,8 @@ clerk/models/ui_operator.py,sha256=mKTJUFZgv7PeEt5oys28HVZxHOJsofmRQOcRpqj0dbU,2
46
45
  clerk/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
46
  clerk/utils/logger.py,sha256=NrMIlJfVmRjjRw_N_Jngkl0qqv7btXUbg5wxcRmFEH4,3800
48
47
  clerk/utils/save_artifact.py,sha256=94aYkYNVGcSUaSWZmdjiY6Oc-3yCKb2XWCZ56IAXQqk,1158
49
- clerk_sdk-0.4.9.dist-info/licenses/LICENSE,sha256=GTVQl3vH6ht70wJXKC0yMT8CmXKHxv_YyO_utAgm7EA,1065
50
- clerk_sdk-0.4.9.dist-info/METADATA,sha256=feCbtDLlu-sYMn7P2ti5kqvQjBDuZ8g6sc4I948wcjo,9936
51
- clerk_sdk-0.4.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
52
- clerk_sdk-0.4.9.dist-info/top_level.txt,sha256=99eQiU6d05_-f41tmSFanfI_SIJeAdh7u9m3LNSfcv4,6
53
- clerk_sdk-0.4.9.dist-info/RECORD,,
48
+ clerk_sdk-0.4.11.dist-info/licenses/LICENSE,sha256=GTVQl3vH6ht70wJXKC0yMT8CmXKHxv_YyO_utAgm7EA,1065
49
+ clerk_sdk-0.4.11.dist-info/METADATA,sha256=rIzbkJ6lW7rpGkhsdzUN2Jtpx_WzlRbJ8-hkLAW_Gmk,9937
50
+ clerk_sdk-0.4.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
51
+ clerk_sdk-0.4.11.dist-info/top_level.txt,sha256=99eQiU6d05_-f41tmSFanfI_SIJeAdh7u9m3LNSfcv4,6
52
+ clerk_sdk-0.4.11.dist-info/RECORD,,
@@ -1,40 +0,0 @@
1
- from typing import Any, Optional
2
- from pydantic import BaseModel, field_validator
3
-
4
-
5
- class ActionString(BaseModel):
6
- """
7
- ActionString class represents a string that represents an action in an application.
8
-
9
- Attributes:
10
- action_string (str): The string representation of the action.
11
- comment (str, optional): An optional comment or description for the action.
12
- interrupt_process (bool, optional): A flag indicating whether the action should interrupt the process.
13
-
14
- Methods:
15
- ensure_format(v: str) -> str:
16
- Validator function that ensures the action string has the correct format.
17
-
18
- """
19
-
20
- action_string: str
21
- action_comment: Optional[str] = None
22
- observation: Optional[str] = None
23
- interrupt_process: Optional[bool] = False
24
-
25
- @field_validator("action_string", mode="before")
26
- @classmethod
27
- def ensure_format(cls, v: Any):
28
- if not isinstance(v, str):
29
- raise ValueError("Action string must be a string")
30
- if not v.endswith(".do()") and not v.startswith("NoAction"):
31
- raise ValueError("Action string must end with '.do()'")
32
- return v
33
-
34
- @field_validator("interrupt_process", mode="before")
35
- def convert_to_bool(cls, v: str | bool | None):
36
- if v is None:
37
- return False
38
- elif isinstance(v, str):
39
- return v.lower() in ["true", "1", "yes"]
40
- return v