Skip to content

Commit 799af6d

Browse files
Private deliverable memo content
1 parent a8dec4c commit 799af6d

2 files changed

Lines changed: 30 additions & 15 deletions

File tree

virtuals_acp/client.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,14 @@ def get_agent(self, wallet_address: str, *, show_hidden_offerings: bool = False)
945945
except Exception as e:
946946
raise ACPError(f"An unexpected error occurred while getting agent: {e}")
947947

948+
def get_memo_content(self, url: str) -> str:
949+
response = self.acp_client.request("GET", url)
950+
951+
if not response:
952+
raise ACPApiError("Failed to get memo content")
953+
954+
return response["content"]
955+
948956

949957
# Rebuild the AcpJob model after VirtualsACP is defined
950958
ACPJob.model_rebuild()

virtuals_acp/job.py

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
from datetime import datetime, timezone, timedelta
1+
import json
2+
import re
23
import time
4+
from datetime import datetime, timezone, timedelta
35
from typing import TYPE_CHECKING, List, Optional, Dict, Any, Union, Literal
4-
56
from pydantic import BaseModel, Field, ConfigDict, PrivateAttr
67

78
from 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

Comments
 (0)