1- from datetime import datetime , timezone , timedelta
1+ import json
2+ import re
23import time
4+ from datetime import datetime , timezone , timedelta
35from typing import TYPE_CHECKING , List , Optional , Dict , Any , Union , Literal
4-
56from pydantic import BaseModel , Field , ConfigDict , PrivateAttr
67
78from virtuals_acp .account import ACPAccount
@@ -57,6 +58,7 @@ class ACPJob(BaseModel):
5758 _requirement : Optional [Union [str , Dict [str , Any ]]] = PrivateAttr (default = None )
5859 _price_type : PriceType = PrivateAttr (default = PriceType .FIXED )
5960 _price_value : float = PrivateAttr (default = 0.0 )
61+ _deliverable : Optional [DeliverablePayload ] = PrivateAttr (default = None )
6062
6163 def model_post_init (self , __context : Any ) -> None :
6264 if self .acp_client :
@@ -139,18 +141,6 @@ def base_fare(self) -> Fare:
139141 def account (self ) -> Optional [ACPAccount ]:
140142 return self .acp_client .get_account_by_job_id (self .id , self .acp_contract_client )
141143
142- @property
143- def deliverable (self ) -> Optional [str ]:
144- """Get the deliverable from the completed memo"""
145- memo = next (
146- (
147- m
148- for m in self .memos
149- if ACPJobPhase (m .next_phase ) == ACPJobPhase .COMPLETED
150- ),
151- None ,
152- )
153- return memo .content if memo else None
154144
155145 @property
156146 def rejection_reason (self ) -> Optional [str ]:
@@ -474,7 +464,7 @@ def latest_memo(self) -> Optional[ACPMemo]:
474464 """Get the latest memo in the job"""
475465 return self .memos [- 1 ] if self .memos else None
476466
477- def _get_memo_by_id (self , memo_id ) -> Optional [ACPMemo ]:
467+ def _get_memo_by_id (self , memo_id : int ) -> Optional [ACPMemo ]:
478468 return next ((m for m in self .memos if m .id == memo_id ), None )
479469
480470 def deliver (self , deliverable : DeliverablePayload ) -> str | None :
@@ -747,4 +737,21 @@ def _deliver_cross_chain_payable(self, client_address: str, amount: FareAmountBa
747737
748738 self .acp_contract_client .handle_operation ([create_memo_op ])
749739
740+ def get_deliverable (self ) -> Optional [DeliverablePayload ]:
741+ deliverable = self ._deliverable
742+ if not deliverable :
743+ return None
744+
745+ if not isinstance (deliverable , str ):
746+ return deliverable
747+
748+ if not re .search (r"api/memo-contents/([0-9]+)$" , deliverable ):
749+ return deliverable
750750
751+ content = self .acp_client .get_memo_content (deliverable )
752+
753+ try :
754+ return json .loads (content )
755+ except (json .JSONDecodeError , TypeError ):
756+ return content
757+
0 commit comments