1- from collections .abc import Callable
2- from typing import Any
1+ from collections .abc import Awaitable , Callable
2+ from typing import Any , TypeVar
33
44import pyport
5- import requests
5+ import requests # type: ignore[import-untyped]
66
7+ from src .client .action_runs import PortActionRunClient
8+ from src .client .actions import PortActionClient
79from src .client .agent import PortAgentClient
810from src .client .blueprints import PortBlueprintClient
911from src .client .entities import PortEntityClient
1012from src .client .scorecards import PortScorecardClient
1113from src .config import config
14+ from src .models .action_run .action_run import ActionRun
15+ from src .models .actions .action import Action
1216from src .models .agent import PortAgentResponse
1317from src .models .agent .port_agent_response import PortAgentTriggerResponse
1418from src .models .blueprints import Blueprint
1519from src .models .entities import EntityResult
1620from src .models .scorecards import Scorecard
1721from src .utils import PortError , logger
1822
23+ T = TypeVar ("T" )
24+
1925
2026class PortClient :
2127 """Client for interacting with the Port API."""
@@ -27,36 +33,41 @@ def __init__(
2733 region : str = "EU" ,
2834 base_url : str = config .port_api_base ,
2935 ):
36+ if not client_id or not client_secret :
37+ logger .warning ("PortClient initialized without credentials" )
38+
3039 self .base_url = base_url
3140 self .client_id = client_id
3241 self .client_secret = client_secret
3342 self .region = region
34-
35- if not client_id or not client_secret :
36- logger .warning ("Port client initialized without credentials" )
37- self ._client = None
38- self .agent = None
39- self .blueprints = None
40- self .entities = None
41- self .scorecards = None
42- else :
43- self ._client = pyport .PortClient (client_id = client_id , client_secret = client_secret , us_region = (region == "US" ))
43+ if client_id and client_secret :
44+ self ._client = pyport .PortClient (
45+ client_id = client_id ,
46+ client_secret = client_secret ,
47+ us_region = (region == "US" ),
48+ )
4449 self .agent = PortAgentClient (self ._client )
4550 self .blueprints = PortBlueprintClient (self ._client )
4651 self .entities = PortEntityClient (self ._client )
4752 self .scorecards = PortScorecardClient (self ._client )
53+ self .actions = PortActionClient (self ._client )
54+ self .action_runs = PortActionRunClient (self ._client )
4855
4956 def handle_http_error (self , e : requests .exceptions .HTTPError ) -> PortError :
5057 result = e .response .json ()
51- message = f"Error in { e .request .method } { e .request .url } - { e .response .status_code } : { result } "
58+ message = (
59+ f"Error in { e .request .method } { e .request .url } - { e .response .status_code } : { result } "
60+ )
5261 logger .error (message )
5362 raise PortError (message )
5463
55- async def wrap_request (self , request : Callable ) -> PortError :
64+ async def wrap_request (self , request : Callable [[], Awaitable [T ]]) -> T :
65+ if self ._client is None :
66+ raise PortError ("PortClient is not properly initialized - missing credentials" )
5667 try :
5768 return await request ()
5869 except requests .exceptions .HTTPError as e :
59- self .handle_http_error (e )
70+ raise self .handle_http_error (e ) from e
6071
6172 async def trigger_agent (self , prompt : str ) -> PortAgentTriggerResponse :
6273 return await self .wrap_request (lambda : self .agent .trigger_agent (prompt ))
@@ -77,36 +88,85 @@ async def update_blueprint(self, blueprint_data: dict[str, Any]) -> Blueprint:
7788 return await self .wrap_request (lambda : self .blueprints .update_blueprint (blueprint_data ))
7889
7990 async def delete_blueprint (self , blueprint_identifier : str ) -> bool :
80- return await self .wrap_request (lambda : self .blueprints .delete_blueprint (blueprint_identifier ))
91+ return await self .wrap_request (
92+ lambda : self .blueprints .delete_blueprint (blueprint_identifier )
93+ )
8194
8295 async def get_entity (self , blueprint_identifier : str , entity_identifier : str ) -> EntityResult :
83- return await self .wrap_request (lambda : self .entities .get_entity (blueprint_identifier , entity_identifier ))
96+ return await self .wrap_request (
97+ lambda : self .entities .get_entity (blueprint_identifier , entity_identifier )
98+ )
8499
85100 async def get_entities (self , blueprint_identifier : str ) -> list [EntityResult ]:
86101 return await self .wrap_request (lambda : self .entities .get_entities (blueprint_identifier ))
87102
88- async def create_entity (self , blueprint_identifier : str , entity_data : dict [str , Any ], query : dict [str , Any ]) -> EntityResult :
89- return await self .wrap_request (lambda : self .entities .create_entity (blueprint_identifier , entity_data , query ))
103+ async def create_entity (
104+ self , blueprint_identifier : str , entity_data : dict [str , Any ], query : dict [str , Any ]
105+ ) -> EntityResult :
106+ return await self .wrap_request (
107+ lambda : self .entities .create_entity (blueprint_identifier , entity_data , query )
108+ )
90109
91- async def update_entity (self , blueprint_identifier : str , entity_identifier : str , entity_data : dict [str , Any ]) -> EntityResult :
92- return await self .wrap_request (lambda : self .entities .update_entity (blueprint_identifier , entity_identifier , entity_data ))
110+ async def update_entity (
111+ self , blueprint_identifier : str , entity_identifier : str , entity_data : dict [str , Any ]
112+ ) -> EntityResult :
113+ return await self .wrap_request (
114+ lambda : self .entities .update_entity (
115+ blueprint_identifier , entity_identifier , entity_data
116+ )
117+ )
93118
94- async def delete_entity (self , blueprint_identifier : str , entity_identifier : str , delete_dependents : bool = False ) -> bool :
119+ async def delete_entity (
120+ self , blueprint_identifier : str , entity_identifier : str , delete_dependents : bool = False
121+ ) -> bool :
95122 return await self .wrap_request (
96- lambda : self .entities .delete_entity (blueprint_identifier , entity_identifier , delete_dependents )
123+ lambda : self .entities .delete_entity (
124+ blueprint_identifier , entity_identifier , delete_dependents
125+ )
97126 )
98127
99128 async def get_scorecard (self , blueprint_id : str , scorecard_id : str ) -> Scorecard :
100- return await self .wrap_request (lambda : self .scorecards .get_scorecard (blueprint_id , scorecard_id ))
129+ return await self .wrap_request (
130+ lambda : self .scorecards .get_scorecard (blueprint_id , scorecard_id )
131+ )
101132
102133 async def get_scorecards (self , blueprint_identifier : str ) -> list [Scorecard ]:
103134 return await self .wrap_request (lambda : self .scorecards .get_scorecards (blueprint_identifier ))
104135
105- async def create_scorecard (self , blueprint_id : str , scorecard_data : dict [str , Any ]) -> Scorecard :
106- return await self .wrap_request (lambda : self .scorecards .create_scorecard (blueprint_id , scorecard_data ))
136+ async def create_scorecard (
137+ self , blueprint_id : str , scorecard_data : dict [str , Any ]
138+ ) -> Scorecard :
139+ return await self .wrap_request (
140+ lambda : self .scorecards .create_scorecard (blueprint_id , scorecard_data )
141+ )
107142
108- async def update_scorecard (self , blueprint_id : str , scorecard_id : str , scorecard_data : dict [str , Any ]) -> Scorecard :
109- return await self .wrap_request (lambda : self .scorecards .update_scorecard (blueprint_id , scorecard_id , scorecard_data ))
143+ async def update_scorecard (
144+ self , blueprint_id : str , scorecard_id : str , scorecard_data : dict [str , Any ]
145+ ) -> Scorecard :
146+ return await self .wrap_request (
147+ lambda : self .scorecards .update_scorecard (blueprint_id , scorecard_id , scorecard_data )
148+ )
110149
111150 async def delete_scorecard (self , scorecard_id : str , blueprint_id : str ) -> bool :
112- return await self .wrap_request (lambda : self .scorecards .delete_scorecard (scorecard_id , blueprint_id ))
151+ return await self .wrap_request (
152+ lambda : self .scorecards .delete_scorecard (scorecard_id , blueprint_id )
153+ )
154+
155+ async def get_all_actions (self , trigger_type : str = "self-service" ) -> list [Action ]:
156+ return await self .wrap_request (lambda : self .actions .get_all_actions (trigger_type ))
157+
158+ async def get_action (self , action_identifier : str ) -> Action :
159+ return await self .wrap_request (lambda : self .actions .get_action (action_identifier ))
160+
161+ async def create_global_action_run (self , action_identifier : str , ** kwargs ) -> ActionRun :
162+ return await self .wrap_request (
163+ lambda : self .action_runs .create_global_action_run (action_identifier , ** kwargs )
164+ )
165+
166+ async def create_entity_action_run (self , action_identifier : str , ** kwargs ) -> ActionRun :
167+ return await self .wrap_request (
168+ lambda : self .action_runs .create_entity_action_run (action_identifier , ** kwargs )
169+ )
170+
171+ async def get_action_run (self , run_id : str ) -> ActionRun :
172+ return await self .wrap_request (lambda : self .action_runs .get_action_run (run_id ))
0 commit comments