55import asyncio
66import json
77import time
8- from typing import Dict , List , Optional , Sequence , Tuple , Type , Union , cast
8+ from collections .abc import Iterable , Mapping
9+ from typing import Dict , List , Literal , Optional , Sequence , Tuple , Type , Union , cast , overload
910
1011import aiohttp
1112from aiohttp import FormData
12- from pydantic import BaseModel
13+ from pydantic import BaseModel , TypeAdapter
1314from pydantic_core import to_jsonable_python
1415from typing_extensions import Any , TypeVar
1516
@@ -30,6 +31,24 @@ class PangeaRequestAsync(PangeaRequestBase):
3031 be set in PangeaConfig.
3132 """
3233
34+ async def delete (self , endpoint : str ) -> None :
35+ """
36+ Makes a DELETE call to a Pangea endpoint.
37+
38+ Args:
39+ endpoint: The Pangea API endpoint.
40+ """
41+
42+ url = self ._url (endpoint )
43+
44+ self .logger .debug (
45+ json .dumps ({"service" : self .service , "action" : "delete" , "url" : url }, default = default_encoder )
46+ )
47+
48+ requests_response = await self ._http_delete (url , headers = self ._headers ())
49+ await self ._check_http_errors (requests_response )
50+
51+ @overload
3352 async def post (
3453 self ,
3554 endpoint : str ,
@@ -38,18 +57,60 @@ async def post(
3857 files : Optional [List [Tuple ]] = None ,
3958 poll_result : bool = True ,
4059 url : Optional [str ] = None ,
60+ * ,
61+ pangea_response : Literal [True ] = True ,
4162 ) -> PangeaResponse [TResult ]:
42- """Makes the POST call to a Pangea Service endpoint.
63+ """
64+ Makes a POST call to a Pangea Service endpoint.
4365
4466 Args:
45- endpoint(str) : The Pangea Service API endpoint.
46- data(dict) : The POST body payload object
67+ endpoint: The Pangea Service API endpoint.
68+ data: The POST body payload object
4769
4870 Returns:
4971 PangeaResponse which contains the response in its entirety and
5072 various properties to retrieve individual fields
5173 """
5274
75+ @overload
76+ async def post (
77+ self ,
78+ endpoint : str ,
79+ result_class : Type [TResult ],
80+ data : str | BaseModel | dict [str , Any ] | None = None ,
81+ files : Optional [List [Tuple ]] = None ,
82+ poll_result : bool = True ,
83+ url : Optional [str ] = None ,
84+ * ,
85+ pangea_response : Literal [False ],
86+ ) -> TResult :
87+ """
88+ Makes a POST call to a Pangea Service endpoint.
89+
90+ Args:
91+ endpoint: The Pangea Service API endpoint.
92+ data: The POST body payload object
93+ """
94+
95+ async def post (
96+ self ,
97+ endpoint : str ,
98+ result_class : Type [TResult ],
99+ data : str | BaseModel | dict [str , Any ] | None = None ,
100+ files : Optional [List [Tuple ]] = None ,
101+ poll_result : bool = True ,
102+ url : Optional [str ] = None ,
103+ * ,
104+ pangea_response : bool = True ,
105+ ) -> PangeaResponse [TResult ] | TResult :
106+ """
107+ Makes a POST call to a Pangea Service endpoint.
108+
109+ Args:
110+ endpoint: The Pangea Service API endpoint.
111+ data: The POST body payload object
112+ """
113+
53114 if isinstance (data , BaseModel ):
54115 data = data .model_dump (exclude_none = True )
55116
@@ -86,9 +147,13 @@ async def post(
86147
87148 await self ._check_http_errors (requests_response )
88149
150+ if not pangea_response :
151+ type_adapter = TypeAdapter (result_class )
152+ return type_adapter .validate_python (await requests_response .json ())
153+
89154 if "multipart/form-data" in requests_response .headers .get ("content-type" , "" ):
90155 multipart_response = await self ._process_multipart_response (requests_response )
91- pangea_response : PangeaResponse = PangeaResponse (
156+ pangea_response_obj : PangeaResponse = PangeaResponse (
92157 requests_response ,
93158 result_class = result_class ,
94159 json = multipart_response .pangea_json ,
@@ -101,47 +166,108 @@ async def post(
101166 json .dumps ({"service" : self .service , "action" : "post" , "url" : url , "response" : json_resp })
102167 )
103168
104- pangea_response = PangeaResponse (requests_response , result_class = result_class , json = json_resp )
169+ pangea_response_obj = PangeaResponse (requests_response , result_class = result_class , json = json_resp )
105170 except aiohttp .ContentTypeError as e :
106171 raise pe .PangeaException (f"Failed to decode json response. { e } . Body: { await requests_response .text ()} " )
107172
108173 if poll_result :
109- pangea_response = await self ._handle_queued_result (pangea_response )
174+ pangea_response_obj = await self ._handle_queued_result (pangea_response_obj )
110175
111- return self ._check_response (pangea_response )
176+ return self ._check_response (pangea_response_obj )
112177
113- async def get (self , path : str , result_class : Type [TResult ], check_response : bool = True ) -> PangeaResponse [TResult ]:
114- """Makes the GET call to a Pangea Service endpoint.
178+ @overload
179+ async def get (
180+ self ,
181+ path : str ,
182+ result_class : Type [TResult ],
183+ check_response : bool = True ,
184+ * ,
185+ params : (
186+ Mapping [str | bytes | int | float , str | bytes | int | float | Iterable [str | bytes | int | float ] | None ]
187+ | None
188+ ) = None ,
189+ pangea_response : Literal [True ] = True ,
190+ ) -> PangeaResponse [TResult ]:
191+ """
192+ Makes the GET call to a Pangea Service endpoint.
115193
116194 Args:
117- endpoint(str): The Pangea Service API endpoint.
118- path(str): Additional URL path
195+ path: Additional URL path
196+ params: Dictionary of querystring data to attach to the request
119197
120198 Returns:
121199 PangeaResponse which contains the response in its entirety and
122200 various properties to retrieve individual fields
123201 """
124202
203+ @overload
204+ async def get (
205+ self ,
206+ path : str ,
207+ result_class : Type [TResult ],
208+ check_response : bool = True ,
209+ * ,
210+ params : (
211+ Mapping [str | bytes | int | float , str | bytes | int | float | Iterable [str | bytes | int | float ] | None ]
212+ | None
213+ ) = None ,
214+ pangea_response : Literal [False ] = False ,
215+ ) -> TResult :
216+ """
217+ Makes the GET call to a Pangea Service endpoint.
218+
219+ Args:
220+ path: Additional URL path
221+ params: Dictionary of querystring data to attach to the request
222+ """
223+
224+ async def get (
225+ self ,
226+ path : str ,
227+ result_class : Type [TResult ],
228+ check_response : bool = True ,
229+ * ,
230+ params : (
231+ Mapping [str | bytes | int | float , str | bytes | int | float | Iterable [str | bytes | int | float ] | None ]
232+ | None
233+ ) = None ,
234+ pangea_response : bool = True ,
235+ ) -> PangeaResponse [TResult ] | TResult :
236+ """
237+ Makes the GET call to a Pangea Service endpoint.
238+
239+ Args:
240+ path: Additional URL path
241+ params: Dictionary of querystring data to attach to the request
242+ pangea_response: Whether or not the response body follows Pangea's
243+ standard response schema
244+ """
245+
125246 url = self ._url (path )
126247 self .logger .debug (json .dumps ({"service" : self .service , "action" : "get" , "url" : url }))
127248
128- async with self .session .get (url , headers = self ._headers ()) as requests_response :
249+ async with self .session .get (url , params = params , headers = self ._headers ()) as requests_response :
129250 await self ._check_http_errors (requests_response )
130- pangea_response = PangeaResponse (
251+
252+ if not pangea_response :
253+ type_adapter = TypeAdapter (result_class )
254+ return type_adapter .validate_python (await requests_response .json ())
255+
256+ pangea_response_obj = PangeaResponse (
131257 requests_response , result_class = result_class , json = await requests_response .json ()
132258 )
133259
134260 self .logger .debug (
135261 json .dumps (
136- {"service" : self .service , "action" : "get" , "url" : url , "response" : pangea_response .json },
262+ {"service" : self .service , "action" : "get" , "url" : url , "response" : pangea_response_obj .json },
137263 default = default_encoder ,
138264 )
139265 )
140266
141267 if check_response is False :
142- return pangea_response
268+ return pangea_response_obj
143269
144- return self ._check_response (pangea_response )
270+ return self ._check_response (pangea_response_obj )
145271
146272 async def _check_http_errors (self , resp : aiohttp .ClientResponse ):
147273 if resp .status == 503 :
@@ -275,10 +401,18 @@ async def _process_multipart_response(self, resp: aiohttp.ClientResponse) -> Mul
275401 attached_files = await self ._get_attached_files (multipart_reader )
276402 return MultipartResponse (pangea_json , attached_files ) # type: ignore[arg-type]
277403
404+ async def _http_delete (
405+ self ,
406+ url : str ,
407+ * ,
408+ headers : Mapping [str , str | bytes | None ] = {},
409+ ) -> aiohttp .ClientResponse :
410+ return await self .session .delete (url , headers = headers )
411+
278412 async def _http_post (
279413 self ,
280414 url : str ,
281- headers : Dict = {},
415+ headers : Mapping [ str , str | bytes | None ] = {},
282416 data : Union [str , Dict ] = {},
283417 files : Optional [List [Tuple ]] = [],
284418 presigned_url_post : bool = False ,
0 commit comments