@@ -2454,8 +2454,9 @@ class ParallelStage(BaseNestedStage):
24542454 This stage is not the low-level stage model because it runs multi-stages
24552455 in this stage execution.
24562456
2457- Data Validate:
2458- >>> stage = {
2457+ Examples:
2458+ >>> stage = ParallelStage.model_validate({
2459+ ... "id": "parallel-stage",
24592460 ... "name": "Parallel stage execution.",
24602461 ... "parallel": {
24612462 ... "branch01": [
@@ -2477,7 +2478,7 @@ class ParallelStage(BaseNestedStage):
24772478 ... },
24782479 ... ],
24792480 ... }
2480- ... }
2481+ ... })
24812482 """
24822483
24832484 parallel : dict [str , list [Stage ]] = Field (
@@ -2727,8 +2728,9 @@ class ForEachStage(BaseNestedStage):
27272728 This stage is not the low-level stage model because it runs
27282729 multi-stages in this stage execution.
27292730
2730- Data Validate:
2731- >>> stage = {
2731+ Examples:
2732+ >>> stage = ForEachStage.model_validate({
2733+ ... "id": "foreach-stage",
27322734 ... "name": "For-each stage execution",
27332735 ... "foreach": [1, 2, 3]
27342736 ... "stages": [
@@ -2737,7 +2739,7 @@ class ForEachStage(BaseNestedStage):
27372739 ... "echo": "Start run with item ${{ item }}"
27382740 ... },
27392741 ... ],
2740- ... }
2742+ ... })
27412743 """
27422744
27432745 foreach : EachType = Field (
@@ -2912,15 +2914,18 @@ def validate_foreach(self, value: Any) -> list[Any]:
29122914 """Validate foreach value that already passed to this model.
29132915
29142916 Args:
2915- value:
2917+ value (Any): An any foreach value.
29162918
29172919 Raises:
29182920 TypeError: If value can not try-convert to list type.
2919- ValueError:
2921+ ValueError: If the foreach value is dict type.
2922+ ValueError: If the foreach value contain duplication item without
2923+ enable using index as key flag.
29202924
29212925 Returns:
29222926 list[Any]: list of item.
29232927 """
2928+ # NOTE: Try to cast a foreach with string type to list of items.
29242929 if isinstance (value , str ):
29252930 try :
29262931 value : list [Any ] = str2list (value )
@@ -2929,6 +2934,7 @@ def validate_foreach(self, value: Any) -> list[Any]:
29292934 f"Does not support string foreach: { value !r} that can "
29302935 f"not convert to list."
29312936 ) from e
2937+
29322938 # [VALIDATE]: Type of the foreach should be `list` type.
29332939 elif isinstance (value , dict ):
29342940 raise TypeError (
@@ -3050,8 +3056,9 @@ class UntilStage(BaseNestedStage):
30503056 This stage is not the low-level stage model because it runs
30513057 multi-stages in this stage execution.
30523058
3053- Data Validate:
3054- >>> stage = {
3059+ Examples:
3060+ >>> stage = UntilStage.model_validate({
3061+ ... "id": "until-stage",
30553062 ... "name": "Until stage execution",
30563063 ... "item": 1,
30573064 ... "until": "${{ item }} > 3"
@@ -3064,7 +3071,7 @@ class UntilStage(BaseNestedStage):
30643071 ... )
30653072 ... },
30663073 ... ],
3067- ... }
3074+ ... })
30683075 """
30693076
30703077 item : Union [str , int , bool ] = Field (
@@ -3335,6 +3342,8 @@ class Match(BaseModel):
33353342
33363343
33373344class Else (BaseModel ):
3345+ """Else model for the Case Stage."""
3346+
33383347 other : list [Stage ] = Field (
33393348 description = "A list of stage that does not match any case." ,
33403349 alias = "else" ,
@@ -3344,8 +3353,9 @@ class Else(BaseModel):
33443353class CaseStage (BaseNestedStage ):
33453354 """Case stage executor that execute all stages if the condition was matched.
33463355
3347- Data Validate:
3348- >>> stage = {
3356+ Examples:
3357+ >>> stage = CaseStage.model_validate({
3358+ ... "id": "case-stage",
33493359 ... "name": "If stage execution.",
33503360 ... "case": "${{ param.test }}",
33513361 ... "match": [
@@ -3368,9 +3378,10 @@ class CaseStage(BaseNestedStage):
33683378 ... ],
33693379 ... },
33703380 ... ],
3371- ... }
3381+ ... })
33723382
3373- >>> stage = {
3383+ >>> stage = CaseStage.model_validate({
3384+ ... "id": "case-stage",
33743385 ... "name": "If stage execution.",
33753386 ... "case": "${{ param.test }}",
33763387 ... "match": [
@@ -3392,7 +3403,7 @@ class CaseStage(BaseNestedStage):
33923403 ... ],
33933404 ... },
33943405 ... ],
3395- ... }
3406+ ... })
33963407
33973408 """
33983409
@@ -3411,9 +3422,16 @@ class CaseStage(BaseNestedStage):
34113422
34123423 @field_validator ("match" , mode = "after" )
34133424 def __validate_match (
3414- cls , match : list [Union [Match , Else ]]
3425+ cls ,
3426+ match : list [Union [Match , Else ]],
34153427 ) -> list [Union [Match , Else ]]:
3416- """Validate the match field should contain only one Else model."""
3428+ """Validate the match field should contain only one Else model.
3429+
3430+ Raises:
3431+ ValueError: If match field contain Else more than 1 model.
3432+ ValueError: If match field contain Match with '_' case (it represent
3433+ the else case) more than 1 model.
3434+ """
34173435 c_else_case : int = 0
34183436 c_else_model : int = 0
34193437 for m in match :
@@ -3612,8 +3630,10 @@ def process(
36123630 case : StrOrNone = param2template (self .case , params , extras = self .extras )
36133631 trace .info (f"[NESTED]: Get Case: { case !r} ." )
36143632 case , stages = self .extract_stages_from_case (case , params = params )
3633+
36153634 if event and event .is_set ():
36163635 raise StageCancelError ("Cancel before start case process." )
3636+
36173637 status , context = self ._process_nested (
36183638 case = case ,
36193639 stages = stages ,
@@ -3635,11 +3655,12 @@ class RaiseStage(BaseAsyncStage):
36353655 """Raise error stage executor that raise `StageError` that use a message
36363656 field for making error message before raise.
36373657
3638- Data Validate:
3639- >>> stage = {
3658+ Examples:
3659+ >>> stage = RaiseStage.model_validate({
3660+ ... "id": "raise-stage",
36403661 ... "name": "Raise stage",
36413662 ... "raise": "raise this stage",
3642- ... }
3663+ ... })
36433664
36443665 """
36453666
@@ -3940,7 +3961,7 @@ class VirtualPyStage(PyStage): # pragma: no cov
39403961 )
39413962
39423963 @contextlib .contextmanager
3943- def create_py_file (
3964+ def make_py_file (
39443965 self ,
39453966 py : str ,
39463967 values : DictData ,
@@ -4016,13 +4037,14 @@ def process(
40164037 - Execution python file with `uv run` via Python subprocess module.
40174038
40184039 Args:
4019- params: A parameter data that want to use in this
4040+ params (DictData) : A parameter data that want to use in this
40204041 execution.
4021- run_id: A running stage ID.
4022- context: A context data.
4023- parent_run_id: A parent running ID. (Default is None)
4024- event: An event manager that use to track parent process
4025- was not force stopped.
4042+ run_id (str): A running stage ID.
4043+ context (DictData): A context data that was passed from handler
4044+ method.
4045+ parent_run_id (str, default None): A parent running ID.
4046+ event (Event, default None): An event manager that use to track
4047+ parent process was not force stopped.
40264048
40274049 Returns:
40284050 Result: The execution result with status and context data.
@@ -4031,12 +4053,18 @@ def process(
40314053 run_id , parent_run_id = parent_run_id , extras = self .extras
40324054 )
40334055 run : str = param2template (dedent (self .run ), params , extras = self .extras )
4034- with self .create_py_file (
4056+ with self .make_py_file (
40354057 py = run ,
40364058 values = param2template (self .vars , params , extras = self .extras ),
40374059 deps = param2template (self .deps , params , extras = self .extras ),
40384060 run_id = run_id ,
40394061 ) as py :
4062+
4063+ if event and event .is_set ():
4064+ raise StageCancelError (
4065+ "Cancel before start virtual python process."
4066+ )
4067+
40404068 trace .debug (f"[STAGE]: Create `{ py } ` file." )
40414069 rs : CompletedProcess = subprocess .run (
40424070 ["python" , "-m" , "uv" , "run" , py , "--no-cache" ],
@@ -4082,6 +4110,18 @@ async def async_process(
40824110 parent_run_id : Optional [str ] = None ,
40834111 event : Optional [Event ] = None ,
40844112 ) -> Result :
4113+ """Async execution method for this Virtual Python stage.
4114+
4115+ Args:
4116+ params (DictData): A parameter data that want to use in this
4117+ execution.
4118+ run_id (str): A running stage ID.
4119+ context (DictData): A context data that was passed from handler
4120+ method.
4121+ parent_run_id (str, default None): A parent running ID.
4122+ event (Event, default None): An event manager that use to track
4123+ parent process was not force stopped.
4124+ """
40854125 raise NotImplementedError (
40864126 "Async process of Virtual Python stage does not implement yet."
40874127 )
0 commit comments