raccoonai 0.1.0a15__py3-none-any.whl → 0.1.0a17__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of raccoonai might be problematic. Click here for more details.
- raccoonai/_base_client.py +207 -233
- raccoonai/_client.py +1 -4
- raccoonai/_models.py +2 -3
- raccoonai/_response.py +1 -1
- raccoonai/_utils/_transform.py +46 -1
- raccoonai/_utils/_typing.py +3 -1
- raccoonai/_utils/_utils.py +9 -1
- raccoonai/_version.py +1 -1
- raccoonai/resources/fleet/extensions.py +1 -6
- raccoonai/resources/fleet/sessions.py +1 -4
- raccoonai/resources/lam/lam.py +3 -7
- raccoonai/resources/lam/tasks.py +1 -4
- raccoonai/resources/tail/apps.py +1 -4
- raccoonai/resources/tail/users.py +1 -4
- raccoonai/types/fleet/extension_get_response.py +0 -1
- raccoonai/types/fleet/extension_upload_response.py +0 -1
- raccoonai/types/fleet/session_logs_response.py +0 -1
- raccoonai/types/tail/user_create_response.py +0 -1
- {raccoonai-0.1.0a15.dist-info → raccoonai-0.1.0a17.dist-info}/METADATA +2 -2
- {raccoonai-0.1.0a15.dist-info → raccoonai-0.1.0a17.dist-info}/RECORD +22 -22
- {raccoonai-0.1.0a15.dist-info → raccoonai-0.1.0a17.dist-info}/WHEEL +0 -0
- {raccoonai-0.1.0a15.dist-info → raccoonai-0.1.0a17.dist-info}/licenses/LICENSE +0 -0
raccoonai/_base_client.py
CHANGED
|
@@ -98,7 +98,11 @@ _StreamT = TypeVar("_StreamT", bound=Stream[Any])
|
|
|
98
98
|
_AsyncStreamT = TypeVar("_AsyncStreamT", bound=AsyncStream[Any])
|
|
99
99
|
|
|
100
100
|
if TYPE_CHECKING:
|
|
101
|
-
from httpx._config import
|
|
101
|
+
from httpx._config import (
|
|
102
|
+
DEFAULT_TIMEOUT_CONFIG, # pyright: ignore[reportPrivateImportUsage]
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
HTTPX_DEFAULT_TIMEOUT = DEFAULT_TIMEOUT_CONFIG
|
|
102
106
|
else:
|
|
103
107
|
try:
|
|
104
108
|
from httpx._config import DEFAULT_TIMEOUT_CONFIG as HTTPX_DEFAULT_TIMEOUT
|
|
@@ -115,6 +119,7 @@ class PageInfo:
|
|
|
115
119
|
|
|
116
120
|
url: URL | NotGiven
|
|
117
121
|
params: Query | NotGiven
|
|
122
|
+
json: Body | NotGiven
|
|
118
123
|
|
|
119
124
|
@overload
|
|
120
125
|
def __init__(
|
|
@@ -130,19 +135,30 @@ class PageInfo:
|
|
|
130
135
|
params: Query,
|
|
131
136
|
) -> None: ...
|
|
132
137
|
|
|
138
|
+
@overload
|
|
139
|
+
def __init__(
|
|
140
|
+
self,
|
|
141
|
+
*,
|
|
142
|
+
json: Body,
|
|
143
|
+
) -> None: ...
|
|
144
|
+
|
|
133
145
|
def __init__(
|
|
134
146
|
self,
|
|
135
147
|
*,
|
|
136
148
|
url: URL | NotGiven = NOT_GIVEN,
|
|
149
|
+
json: Body | NotGiven = NOT_GIVEN,
|
|
137
150
|
params: Query | NotGiven = NOT_GIVEN,
|
|
138
151
|
) -> None:
|
|
139
152
|
self.url = url
|
|
153
|
+
self.json = json
|
|
140
154
|
self.params = params
|
|
141
155
|
|
|
142
156
|
@override
|
|
143
157
|
def __repr__(self) -> str:
|
|
144
158
|
if self.url:
|
|
145
159
|
return f"{self.__class__.__name__}(url={self.url})"
|
|
160
|
+
if self.json:
|
|
161
|
+
return f"{self.__class__.__name__}(json={self.json})"
|
|
146
162
|
return f"{self.__class__.__name__}(params={self.params})"
|
|
147
163
|
|
|
148
164
|
|
|
@@ -191,6 +207,19 @@ class BasePage(GenericModel, Generic[_T]):
|
|
|
191
207
|
options.url = str(url)
|
|
192
208
|
return options
|
|
193
209
|
|
|
210
|
+
if not isinstance(info.json, NotGiven):
|
|
211
|
+
if not is_mapping(info.json):
|
|
212
|
+
raise TypeError("Pagination is only supported with mappings")
|
|
213
|
+
|
|
214
|
+
if not options.json_data:
|
|
215
|
+
options.json_data = {**info.json}
|
|
216
|
+
else:
|
|
217
|
+
if not is_mapping(options.json_data):
|
|
218
|
+
raise TypeError("Pagination is only supported with mappings")
|
|
219
|
+
|
|
220
|
+
options.json_data = {**options.json_data, **info.json}
|
|
221
|
+
return options
|
|
222
|
+
|
|
194
223
|
raise ValueError("Unexpected PageInfo state")
|
|
195
224
|
|
|
196
225
|
|
|
@@ -408,8 +437,8 @@ class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
|
|
|
408
437
|
headers = httpx.Headers(headers_dict)
|
|
409
438
|
|
|
410
439
|
idempotency_header = self._idempotency_header
|
|
411
|
-
if idempotency_header and options.
|
|
412
|
-
headers[idempotency_header] = options.idempotency_key
|
|
440
|
+
if idempotency_header and options.idempotency_key and idempotency_header not in headers:
|
|
441
|
+
headers[idempotency_header] = options.idempotency_key
|
|
413
442
|
|
|
414
443
|
# Don't set these headers if they were already set or removed by the caller. We check
|
|
415
444
|
# `custom_headers`, which can contain `Omit()`, instead of `headers` to account for the removal case.
|
|
@@ -873,7 +902,6 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
|
|
|
873
902
|
self,
|
|
874
903
|
cast_to: Type[ResponseT],
|
|
875
904
|
options: FinalRequestOptions,
|
|
876
|
-
remaining_retries: Optional[int] = None,
|
|
877
905
|
*,
|
|
878
906
|
stream: Literal[True],
|
|
879
907
|
stream_cls: Type[_StreamT],
|
|
@@ -884,7 +912,6 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
|
|
|
884
912
|
self,
|
|
885
913
|
cast_to: Type[ResponseT],
|
|
886
914
|
options: FinalRequestOptions,
|
|
887
|
-
remaining_retries: Optional[int] = None,
|
|
888
915
|
*,
|
|
889
916
|
stream: Literal[False] = False,
|
|
890
917
|
) -> ResponseT: ...
|
|
@@ -894,7 +921,6 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
|
|
|
894
921
|
self,
|
|
895
922
|
cast_to: Type[ResponseT],
|
|
896
923
|
options: FinalRequestOptions,
|
|
897
|
-
remaining_retries: Optional[int] = None,
|
|
898
924
|
*,
|
|
899
925
|
stream: bool = False,
|
|
900
926
|
stream_cls: Type[_StreamT] | None = None,
|
|
@@ -904,121 +930,109 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
|
|
|
904
930
|
self,
|
|
905
931
|
cast_to: Type[ResponseT],
|
|
906
932
|
options: FinalRequestOptions,
|
|
907
|
-
remaining_retries: Optional[int] = None,
|
|
908
933
|
*,
|
|
909
934
|
stream: bool = False,
|
|
910
935
|
stream_cls: type[_StreamT] | None = None,
|
|
911
936
|
) -> ResponseT | _StreamT:
|
|
912
|
-
|
|
913
|
-
retries_taken = options.get_max_retries(self.max_retries) - remaining_retries
|
|
914
|
-
else:
|
|
915
|
-
retries_taken = 0
|
|
916
|
-
|
|
917
|
-
return self._request(
|
|
918
|
-
cast_to=cast_to,
|
|
919
|
-
options=options,
|
|
920
|
-
stream=stream,
|
|
921
|
-
stream_cls=stream_cls,
|
|
922
|
-
retries_taken=retries_taken,
|
|
923
|
-
)
|
|
937
|
+
cast_to = self._maybe_override_cast_to(cast_to, options)
|
|
924
938
|
|
|
925
|
-
def _request(
|
|
926
|
-
self,
|
|
927
|
-
*,
|
|
928
|
-
cast_to: Type[ResponseT],
|
|
929
|
-
options: FinalRequestOptions,
|
|
930
|
-
retries_taken: int,
|
|
931
|
-
stream: bool,
|
|
932
|
-
stream_cls: type[_StreamT] | None,
|
|
933
|
-
) -> ResponseT | _StreamT:
|
|
934
939
|
# create a copy of the options we were given so that if the
|
|
935
940
|
# options are mutated later & we then retry, the retries are
|
|
936
941
|
# given the original options
|
|
937
942
|
input_options = model_copy(options)
|
|
943
|
+
if input_options.idempotency_key is None and input_options.method.lower() != "get":
|
|
944
|
+
# ensure the idempotency key is reused between requests
|
|
945
|
+
input_options.idempotency_key = self._idempotency_key()
|
|
938
946
|
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
remaining_retries = options.get_max_retries(self.max_retries) - retries_taken
|
|
943
|
-
request = self._build_request(options, retries_taken=retries_taken)
|
|
944
|
-
self._prepare_request(request)
|
|
945
|
-
|
|
946
|
-
kwargs: HttpxSendArgs = {}
|
|
947
|
-
if self.custom_auth is not None:
|
|
948
|
-
kwargs["auth"] = self.custom_auth
|
|
947
|
+
response: httpx.Response | None = None
|
|
948
|
+
max_retries = input_options.get_max_retries(self.max_retries)
|
|
949
949
|
|
|
950
|
-
|
|
950
|
+
retries_taken = 0
|
|
951
|
+
for retries_taken in range(max_retries + 1):
|
|
952
|
+
options = model_copy(input_options)
|
|
953
|
+
options = self._prepare_options(options)
|
|
951
954
|
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
stream=stream or self._should_stream_response_body(request=request),
|
|
956
|
-
**kwargs,
|
|
957
|
-
)
|
|
958
|
-
except httpx.TimeoutException as err:
|
|
959
|
-
log.debug("Encountered httpx.TimeoutException", exc_info=True)
|
|
955
|
+
remaining_retries = max_retries - retries_taken
|
|
956
|
+
request = self._build_request(options, retries_taken=retries_taken)
|
|
957
|
+
self._prepare_request(request)
|
|
960
958
|
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
cast_to,
|
|
965
|
-
retries_taken=retries_taken,
|
|
966
|
-
stream=stream,
|
|
967
|
-
stream_cls=stream_cls,
|
|
968
|
-
response_headers=None,
|
|
969
|
-
)
|
|
959
|
+
kwargs: HttpxSendArgs = {}
|
|
960
|
+
if self.custom_auth is not None:
|
|
961
|
+
kwargs["auth"] = self.custom_auth
|
|
970
962
|
|
|
971
|
-
log.debug("
|
|
972
|
-
raise APITimeoutError(request=request) from err
|
|
973
|
-
except Exception as err:
|
|
974
|
-
log.debug("Encountered Exception", exc_info=True)
|
|
963
|
+
log.debug("Sending HTTP Request: %s %s", request.method, request.url)
|
|
975
964
|
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
stream_cls=stream_cls,
|
|
983
|
-
response_headers=None,
|
|
965
|
+
response = None
|
|
966
|
+
try:
|
|
967
|
+
response = self._client.send(
|
|
968
|
+
request,
|
|
969
|
+
stream=stream or self._should_stream_response_body(request=request),
|
|
970
|
+
**kwargs,
|
|
984
971
|
)
|
|
972
|
+
except httpx.TimeoutException as err:
|
|
973
|
+
log.debug("Encountered httpx.TimeoutException", exc_info=True)
|
|
974
|
+
|
|
975
|
+
if remaining_retries > 0:
|
|
976
|
+
self._sleep_for_retry(
|
|
977
|
+
retries_taken=retries_taken,
|
|
978
|
+
max_retries=max_retries,
|
|
979
|
+
options=input_options,
|
|
980
|
+
response=None,
|
|
981
|
+
)
|
|
982
|
+
continue
|
|
983
|
+
|
|
984
|
+
log.debug("Raising timeout error")
|
|
985
|
+
raise APITimeoutError(request=request) from err
|
|
986
|
+
except Exception as err:
|
|
987
|
+
log.debug("Encountered Exception", exc_info=True)
|
|
988
|
+
|
|
989
|
+
if remaining_retries > 0:
|
|
990
|
+
self._sleep_for_retry(
|
|
991
|
+
retries_taken=retries_taken,
|
|
992
|
+
max_retries=max_retries,
|
|
993
|
+
options=input_options,
|
|
994
|
+
response=None,
|
|
995
|
+
)
|
|
996
|
+
continue
|
|
997
|
+
|
|
998
|
+
log.debug("Raising connection error")
|
|
999
|
+
raise APIConnectionError(request=request) from err
|
|
1000
|
+
|
|
1001
|
+
log.debug(
|
|
1002
|
+
'HTTP Response: %s %s "%i %s" %s',
|
|
1003
|
+
request.method,
|
|
1004
|
+
request.url,
|
|
1005
|
+
response.status_code,
|
|
1006
|
+
response.reason_phrase,
|
|
1007
|
+
response.headers,
|
|
1008
|
+
)
|
|
985
1009
|
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
1010
|
+
try:
|
|
1011
|
+
response.raise_for_status()
|
|
1012
|
+
except httpx.HTTPStatusError as err: # thrown on 4xx and 5xx status code
|
|
1013
|
+
log.debug("Encountered httpx.HTTPStatusError", exc_info=True)
|
|
1014
|
+
|
|
1015
|
+
if remaining_retries > 0 and self._should_retry(err.response):
|
|
1016
|
+
err.response.close()
|
|
1017
|
+
self._sleep_for_retry(
|
|
1018
|
+
retries_taken=retries_taken,
|
|
1019
|
+
max_retries=max_retries,
|
|
1020
|
+
options=input_options,
|
|
1021
|
+
response=response,
|
|
1022
|
+
)
|
|
1023
|
+
continue
|
|
997
1024
|
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
if remaining_retries > 0 and self._should_retry(err.response):
|
|
1004
|
-
err.response.close()
|
|
1005
|
-
return self._retry_request(
|
|
1006
|
-
input_options,
|
|
1007
|
-
cast_to,
|
|
1008
|
-
retries_taken=retries_taken,
|
|
1009
|
-
response_headers=err.response.headers,
|
|
1010
|
-
stream=stream,
|
|
1011
|
-
stream_cls=stream_cls,
|
|
1012
|
-
)
|
|
1025
|
+
# If the response is streamed then we need to explicitly read the response
|
|
1026
|
+
# to completion before attempting to access the response text.
|
|
1027
|
+
if not err.response.is_closed:
|
|
1028
|
+
err.response.read()
|
|
1013
1029
|
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
if not err.response.is_closed:
|
|
1017
|
-
err.response.read()
|
|
1030
|
+
log.debug("Re-raising status error")
|
|
1031
|
+
raise self._make_status_error_from_response(err.response) from None
|
|
1018
1032
|
|
|
1019
|
-
|
|
1020
|
-
raise self._make_status_error_from_response(err.response) from None
|
|
1033
|
+
break
|
|
1021
1034
|
|
|
1035
|
+
assert response is not None, "could not resolve response (should never happen)"
|
|
1022
1036
|
return self._process_response(
|
|
1023
1037
|
cast_to=cast_to,
|
|
1024
1038
|
options=options,
|
|
@@ -1028,37 +1042,20 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
|
|
|
1028
1042
|
retries_taken=retries_taken,
|
|
1029
1043
|
)
|
|
1030
1044
|
|
|
1031
|
-
def
|
|
1032
|
-
self,
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
*,
|
|
1036
|
-
retries_taken: int,
|
|
1037
|
-
response_headers: httpx.Headers | None,
|
|
1038
|
-
stream: bool,
|
|
1039
|
-
stream_cls: type[_StreamT] | None,
|
|
1040
|
-
) -> ResponseT | _StreamT:
|
|
1041
|
-
remaining_retries = options.get_max_retries(self.max_retries) - retries_taken
|
|
1045
|
+
def _sleep_for_retry(
|
|
1046
|
+
self, *, retries_taken: int, max_retries: int, options: FinalRequestOptions, response: httpx.Response | None
|
|
1047
|
+
) -> None:
|
|
1048
|
+
remaining_retries = max_retries - retries_taken
|
|
1042
1049
|
if remaining_retries == 1:
|
|
1043
1050
|
log.debug("1 retry left")
|
|
1044
1051
|
else:
|
|
1045
1052
|
log.debug("%i retries left", remaining_retries)
|
|
1046
1053
|
|
|
1047
|
-
timeout = self._calculate_retry_timeout(remaining_retries, options,
|
|
1054
|
+
timeout = self._calculate_retry_timeout(remaining_retries, options, response.headers if response else None)
|
|
1048
1055
|
log.info("Retrying request to %s in %f seconds", options.url, timeout)
|
|
1049
1056
|
|
|
1050
|
-
# In a synchronous context we are blocking the entire thread. Up to the library user to run the client in a
|
|
1051
|
-
# different thread if necessary.
|
|
1052
1057
|
time.sleep(timeout)
|
|
1053
1058
|
|
|
1054
|
-
return self._request(
|
|
1055
|
-
options=options,
|
|
1056
|
-
cast_to=cast_to,
|
|
1057
|
-
retries_taken=retries_taken + 1,
|
|
1058
|
-
stream=stream,
|
|
1059
|
-
stream_cls=stream_cls,
|
|
1060
|
-
)
|
|
1061
|
-
|
|
1062
1059
|
def _process_response(
|
|
1063
1060
|
self,
|
|
1064
1061
|
*,
|
|
@@ -1402,7 +1399,6 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
|
|
|
1402
1399
|
options: FinalRequestOptions,
|
|
1403
1400
|
*,
|
|
1404
1401
|
stream: Literal[False] = False,
|
|
1405
|
-
remaining_retries: Optional[int] = None,
|
|
1406
1402
|
) -> ResponseT: ...
|
|
1407
1403
|
|
|
1408
1404
|
@overload
|
|
@@ -1413,7 +1409,6 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
|
|
|
1413
1409
|
*,
|
|
1414
1410
|
stream: Literal[True],
|
|
1415
1411
|
stream_cls: type[_AsyncStreamT],
|
|
1416
|
-
remaining_retries: Optional[int] = None,
|
|
1417
1412
|
) -> _AsyncStreamT: ...
|
|
1418
1413
|
|
|
1419
1414
|
@overload
|
|
@@ -1424,7 +1419,6 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
|
|
|
1424
1419
|
*,
|
|
1425
1420
|
stream: bool,
|
|
1426
1421
|
stream_cls: type[_AsyncStreamT] | None = None,
|
|
1427
|
-
remaining_retries: Optional[int] = None,
|
|
1428
1422
|
) -> ResponseT | _AsyncStreamT: ...
|
|
1429
1423
|
|
|
1430
1424
|
async def request(
|
|
@@ -1434,116 +1428,111 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
|
|
|
1434
1428
|
*,
|
|
1435
1429
|
stream: bool = False,
|
|
1436
1430
|
stream_cls: type[_AsyncStreamT] | None = None,
|
|
1437
|
-
remaining_retries: Optional[int] = None,
|
|
1438
|
-
) -> ResponseT | _AsyncStreamT:
|
|
1439
|
-
if remaining_retries is not None:
|
|
1440
|
-
retries_taken = options.get_max_retries(self.max_retries) - remaining_retries
|
|
1441
|
-
else:
|
|
1442
|
-
retries_taken = 0
|
|
1443
|
-
|
|
1444
|
-
return await self._request(
|
|
1445
|
-
cast_to=cast_to,
|
|
1446
|
-
options=options,
|
|
1447
|
-
stream=stream,
|
|
1448
|
-
stream_cls=stream_cls,
|
|
1449
|
-
retries_taken=retries_taken,
|
|
1450
|
-
)
|
|
1451
|
-
|
|
1452
|
-
async def _request(
|
|
1453
|
-
self,
|
|
1454
|
-
cast_to: Type[ResponseT],
|
|
1455
|
-
options: FinalRequestOptions,
|
|
1456
|
-
*,
|
|
1457
|
-
stream: bool,
|
|
1458
|
-
stream_cls: type[_AsyncStreamT] | None,
|
|
1459
|
-
retries_taken: int,
|
|
1460
1431
|
) -> ResponseT | _AsyncStreamT:
|
|
1461
1432
|
if self._platform is None:
|
|
1462
1433
|
# `get_platform` can make blocking IO calls so we
|
|
1463
1434
|
# execute it earlier while we are in an async context
|
|
1464
1435
|
self._platform = await asyncify(get_platform)()
|
|
1465
1436
|
|
|
1437
|
+
cast_to = self._maybe_override_cast_to(cast_to, options)
|
|
1438
|
+
|
|
1466
1439
|
# create a copy of the options we were given so that if the
|
|
1467
1440
|
# options are mutated later & we then retry, the retries are
|
|
1468
1441
|
# given the original options
|
|
1469
1442
|
input_options = model_copy(options)
|
|
1443
|
+
if input_options.idempotency_key is None and input_options.method.lower() != "get":
|
|
1444
|
+
# ensure the idempotency key is reused between requests
|
|
1445
|
+
input_options.idempotency_key = self._idempotency_key()
|
|
1470
1446
|
|
|
1471
|
-
|
|
1472
|
-
|
|
1447
|
+
response: httpx.Response | None = None
|
|
1448
|
+
max_retries = input_options.get_max_retries(self.max_retries)
|
|
1473
1449
|
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1450
|
+
retries_taken = 0
|
|
1451
|
+
for retries_taken in range(max_retries + 1):
|
|
1452
|
+
options = model_copy(input_options)
|
|
1453
|
+
options = await self._prepare_options(options)
|
|
1477
1454
|
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1455
|
+
remaining_retries = max_retries - retries_taken
|
|
1456
|
+
request = self._build_request(options, retries_taken=retries_taken)
|
|
1457
|
+
await self._prepare_request(request)
|
|
1481
1458
|
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
stream=stream or self._should_stream_response_body(request=request),
|
|
1486
|
-
**kwargs,
|
|
1487
|
-
)
|
|
1488
|
-
except httpx.TimeoutException as err:
|
|
1489
|
-
log.debug("Encountered httpx.TimeoutException", exc_info=True)
|
|
1490
|
-
|
|
1491
|
-
if remaining_retries > 0:
|
|
1492
|
-
return await self._retry_request(
|
|
1493
|
-
input_options,
|
|
1494
|
-
cast_to,
|
|
1495
|
-
retries_taken=retries_taken,
|
|
1496
|
-
stream=stream,
|
|
1497
|
-
stream_cls=stream_cls,
|
|
1498
|
-
response_headers=None,
|
|
1499
|
-
)
|
|
1459
|
+
kwargs: HttpxSendArgs = {}
|
|
1460
|
+
if self.custom_auth is not None:
|
|
1461
|
+
kwargs["auth"] = self.custom_auth
|
|
1500
1462
|
|
|
1501
|
-
log.debug("
|
|
1502
|
-
raise APITimeoutError(request=request) from err
|
|
1503
|
-
except Exception as err:
|
|
1504
|
-
log.debug("Encountered Exception", exc_info=True)
|
|
1463
|
+
log.debug("Sending HTTP Request: %s %s", request.method, request.url)
|
|
1505
1464
|
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
stream_cls=stream_cls,
|
|
1513
|
-
response_headers=None,
|
|
1465
|
+
response = None
|
|
1466
|
+
try:
|
|
1467
|
+
response = await self._client.send(
|
|
1468
|
+
request,
|
|
1469
|
+
stream=stream or self._should_stream_response_body(request=request),
|
|
1470
|
+
**kwargs,
|
|
1514
1471
|
)
|
|
1472
|
+
except httpx.TimeoutException as err:
|
|
1473
|
+
log.debug("Encountered httpx.TimeoutException", exc_info=True)
|
|
1474
|
+
|
|
1475
|
+
if remaining_retries > 0:
|
|
1476
|
+
await self._sleep_for_retry(
|
|
1477
|
+
retries_taken=retries_taken,
|
|
1478
|
+
max_retries=max_retries,
|
|
1479
|
+
options=input_options,
|
|
1480
|
+
response=None,
|
|
1481
|
+
)
|
|
1482
|
+
continue
|
|
1483
|
+
|
|
1484
|
+
log.debug("Raising timeout error")
|
|
1485
|
+
raise APITimeoutError(request=request) from err
|
|
1486
|
+
except Exception as err:
|
|
1487
|
+
log.debug("Encountered Exception", exc_info=True)
|
|
1488
|
+
|
|
1489
|
+
if remaining_retries > 0:
|
|
1490
|
+
await self._sleep_for_retry(
|
|
1491
|
+
retries_taken=retries_taken,
|
|
1492
|
+
max_retries=max_retries,
|
|
1493
|
+
options=input_options,
|
|
1494
|
+
response=None,
|
|
1495
|
+
)
|
|
1496
|
+
continue
|
|
1497
|
+
|
|
1498
|
+
log.debug("Raising connection error")
|
|
1499
|
+
raise APIConnectionError(request=request) from err
|
|
1500
|
+
|
|
1501
|
+
log.debug(
|
|
1502
|
+
'HTTP Response: %s %s "%i %s" %s',
|
|
1503
|
+
request.method,
|
|
1504
|
+
request.url,
|
|
1505
|
+
response.status_code,
|
|
1506
|
+
response.reason_phrase,
|
|
1507
|
+
response.headers,
|
|
1508
|
+
)
|
|
1515
1509
|
|
|
1516
|
-
|
|
1517
|
-
|
|
1510
|
+
try:
|
|
1511
|
+
response.raise_for_status()
|
|
1512
|
+
except httpx.HTTPStatusError as err: # thrown on 4xx and 5xx status code
|
|
1513
|
+
log.debug("Encountered httpx.HTTPStatusError", exc_info=True)
|
|
1514
|
+
|
|
1515
|
+
if remaining_retries > 0 and self._should_retry(err.response):
|
|
1516
|
+
await err.response.aclose()
|
|
1517
|
+
await self._sleep_for_retry(
|
|
1518
|
+
retries_taken=retries_taken,
|
|
1519
|
+
max_retries=max_retries,
|
|
1520
|
+
options=input_options,
|
|
1521
|
+
response=response,
|
|
1522
|
+
)
|
|
1523
|
+
continue
|
|
1518
1524
|
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1525
|
+
# If the response is streamed then we need to explicitly read the response
|
|
1526
|
+
# to completion before attempting to access the response text.
|
|
1527
|
+
if not err.response.is_closed:
|
|
1528
|
+
await err.response.aread()
|
|
1522
1529
|
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
except httpx.HTTPStatusError as err: # thrown on 4xx and 5xx status code
|
|
1526
|
-
log.debug("Encountered httpx.HTTPStatusError", exc_info=True)
|
|
1527
|
-
|
|
1528
|
-
if remaining_retries > 0 and self._should_retry(err.response):
|
|
1529
|
-
await err.response.aclose()
|
|
1530
|
-
return await self._retry_request(
|
|
1531
|
-
input_options,
|
|
1532
|
-
cast_to,
|
|
1533
|
-
retries_taken=retries_taken,
|
|
1534
|
-
response_headers=err.response.headers,
|
|
1535
|
-
stream=stream,
|
|
1536
|
-
stream_cls=stream_cls,
|
|
1537
|
-
)
|
|
1530
|
+
log.debug("Re-raising status error")
|
|
1531
|
+
raise self._make_status_error_from_response(err.response) from None
|
|
1538
1532
|
|
|
1539
|
-
|
|
1540
|
-
# to completion before attempting to access the response text.
|
|
1541
|
-
if not err.response.is_closed:
|
|
1542
|
-
await err.response.aread()
|
|
1543
|
-
|
|
1544
|
-
log.debug("Re-raising status error")
|
|
1545
|
-
raise self._make_status_error_from_response(err.response) from None
|
|
1533
|
+
break
|
|
1546
1534
|
|
|
1535
|
+
assert response is not None, "could not resolve response (should never happen)"
|
|
1547
1536
|
return await self._process_response(
|
|
1548
1537
|
cast_to=cast_to,
|
|
1549
1538
|
options=options,
|
|
@@ -1553,35 +1542,20 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
|
|
|
1553
1542
|
retries_taken=retries_taken,
|
|
1554
1543
|
)
|
|
1555
1544
|
|
|
1556
|
-
async def
|
|
1557
|
-
self,
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
*,
|
|
1561
|
-
retries_taken: int,
|
|
1562
|
-
response_headers: httpx.Headers | None,
|
|
1563
|
-
stream: bool,
|
|
1564
|
-
stream_cls: type[_AsyncStreamT] | None,
|
|
1565
|
-
) -> ResponseT | _AsyncStreamT:
|
|
1566
|
-
remaining_retries = options.get_max_retries(self.max_retries) - retries_taken
|
|
1545
|
+
async def _sleep_for_retry(
|
|
1546
|
+
self, *, retries_taken: int, max_retries: int, options: FinalRequestOptions, response: httpx.Response | None
|
|
1547
|
+
) -> None:
|
|
1548
|
+
remaining_retries = max_retries - retries_taken
|
|
1567
1549
|
if remaining_retries == 1:
|
|
1568
1550
|
log.debug("1 retry left")
|
|
1569
1551
|
else:
|
|
1570
1552
|
log.debug("%i retries left", remaining_retries)
|
|
1571
1553
|
|
|
1572
|
-
timeout = self._calculate_retry_timeout(remaining_retries, options,
|
|
1554
|
+
timeout = self._calculate_retry_timeout(remaining_retries, options, response.headers if response else None)
|
|
1573
1555
|
log.info("Retrying request to %s in %f seconds", options.url, timeout)
|
|
1574
1556
|
|
|
1575
1557
|
await anyio.sleep(timeout)
|
|
1576
1558
|
|
|
1577
|
-
return await self._request(
|
|
1578
|
-
options=options,
|
|
1579
|
-
cast_to=cast_to,
|
|
1580
|
-
retries_taken=retries_taken + 1,
|
|
1581
|
-
stream=stream,
|
|
1582
|
-
stream_cls=stream_cls,
|
|
1583
|
-
)
|
|
1584
|
-
|
|
1585
1559
|
async def _process_response(
|
|
1586
1560
|
self,
|
|
1587
1561
|
*,
|
raccoonai/_client.py
CHANGED
|
@@ -19,10 +19,7 @@ from ._types import (
|
|
|
19
19
|
ProxiesTypes,
|
|
20
20
|
RequestOptions,
|
|
21
21
|
)
|
|
22
|
-
from ._utils import
|
|
23
|
-
is_given,
|
|
24
|
-
get_async_library,
|
|
25
|
-
)
|
|
22
|
+
from ._utils import is_given, get_async_library
|
|
26
23
|
from ._version import __version__
|
|
27
24
|
from ._streaming import Stream as Stream, AsyncStream as AsyncStream
|
|
28
25
|
from ._exceptions import APIStatusError, RaccoonAIError
|
raccoonai/_models.py
CHANGED
|
@@ -19,7 +19,6 @@ from typing_extensions import (
|
|
|
19
19
|
)
|
|
20
20
|
|
|
21
21
|
import pydantic
|
|
22
|
-
import pydantic.generics
|
|
23
22
|
from pydantic.fields import FieldInfo
|
|
24
23
|
|
|
25
24
|
from ._types import (
|
|
@@ -627,8 +626,8 @@ def _build_discriminated_union_meta(*, union: type, meta_annotations: tuple[Any,
|
|
|
627
626
|
# Note: if one variant defines an alias then they all should
|
|
628
627
|
discriminator_alias = field_info.alias
|
|
629
628
|
|
|
630
|
-
if field_info
|
|
631
|
-
for entry in get_args(
|
|
629
|
+
if (annotation := getattr(field_info, "annotation", None)) and is_literal_type(annotation):
|
|
630
|
+
for entry in get_args(annotation):
|
|
632
631
|
if isinstance(entry, str):
|
|
633
632
|
mapping[entry] = variant
|
|
634
633
|
|
raccoonai/_response.py
CHANGED
|
@@ -233,7 +233,7 @@ class BaseAPIResponse(Generic[R]):
|
|
|
233
233
|
# split is required to handle cases where additional information is included
|
|
234
234
|
# in the response, e.g. application/json; charset=utf-8
|
|
235
235
|
content_type, *_ = response.headers.get("content-type", "*").split(";")
|
|
236
|
-
if content_type
|
|
236
|
+
if not content_type.endswith("json"):
|
|
237
237
|
if is_basemodel(cast_to):
|
|
238
238
|
try:
|
|
239
239
|
data = response.json()
|
raccoonai/_utils/_transform.py
CHANGED
|
@@ -5,13 +5,15 @@ import base64
|
|
|
5
5
|
import pathlib
|
|
6
6
|
from typing import Any, Mapping, TypeVar, cast
|
|
7
7
|
from datetime import date, datetime
|
|
8
|
-
from typing_extensions import Literal, get_args, override, get_type_hints
|
|
8
|
+
from typing_extensions import Literal, get_args, override, get_type_hints as _get_type_hints
|
|
9
9
|
|
|
10
10
|
import anyio
|
|
11
11
|
import pydantic
|
|
12
12
|
|
|
13
13
|
from ._utils import (
|
|
14
14
|
is_list,
|
|
15
|
+
is_given,
|
|
16
|
+
lru_cache,
|
|
15
17
|
is_mapping,
|
|
16
18
|
is_iterable,
|
|
17
19
|
)
|
|
@@ -108,6 +110,7 @@ def transform(
|
|
|
108
110
|
return cast(_T, transformed)
|
|
109
111
|
|
|
110
112
|
|
|
113
|
+
@lru_cache(maxsize=8096)
|
|
111
114
|
def _get_annotated_type(type_: type) -> type | None:
|
|
112
115
|
"""If the given type is an `Annotated` type then it is returned, if not `None` is returned.
|
|
113
116
|
|
|
@@ -142,6 +145,10 @@ def _maybe_transform_key(key: str, type_: type) -> str:
|
|
|
142
145
|
return key
|
|
143
146
|
|
|
144
147
|
|
|
148
|
+
def _no_transform_needed(annotation: type) -> bool:
|
|
149
|
+
return annotation == float or annotation == int
|
|
150
|
+
|
|
151
|
+
|
|
145
152
|
def _transform_recursive(
|
|
146
153
|
data: object,
|
|
147
154
|
*,
|
|
@@ -184,6 +191,15 @@ def _transform_recursive(
|
|
|
184
191
|
return cast(object, data)
|
|
185
192
|
|
|
186
193
|
inner_type = extract_type_arg(stripped_type, 0)
|
|
194
|
+
if _no_transform_needed(inner_type):
|
|
195
|
+
# for some types there is no need to transform anything, so we can get a small
|
|
196
|
+
# perf boost from skipping that work.
|
|
197
|
+
#
|
|
198
|
+
# but we still need to convert to a list to ensure the data is json-serializable
|
|
199
|
+
if is_list(data):
|
|
200
|
+
return data
|
|
201
|
+
return list(data)
|
|
202
|
+
|
|
187
203
|
return [_transform_recursive(d, annotation=annotation, inner_type=inner_type) for d in data]
|
|
188
204
|
|
|
189
205
|
if is_union_type(stripped_type):
|
|
@@ -245,6 +261,11 @@ def _transform_typeddict(
|
|
|
245
261
|
result: dict[str, object] = {}
|
|
246
262
|
annotations = get_type_hints(expected_type, include_extras=True)
|
|
247
263
|
for key, value in data.items():
|
|
264
|
+
if not is_given(value):
|
|
265
|
+
# we don't need to include `NotGiven` values here as they'll
|
|
266
|
+
# be stripped out before the request is sent anyway
|
|
267
|
+
continue
|
|
268
|
+
|
|
248
269
|
type_ = annotations.get(key)
|
|
249
270
|
if type_ is None:
|
|
250
271
|
# we do not have a type annotation for this field, leave it as is
|
|
@@ -332,6 +353,15 @@ async def _async_transform_recursive(
|
|
|
332
353
|
return cast(object, data)
|
|
333
354
|
|
|
334
355
|
inner_type = extract_type_arg(stripped_type, 0)
|
|
356
|
+
if _no_transform_needed(inner_type):
|
|
357
|
+
# for some types there is no need to transform anything, so we can get a small
|
|
358
|
+
# perf boost from skipping that work.
|
|
359
|
+
#
|
|
360
|
+
# but we still need to convert to a list to ensure the data is json-serializable
|
|
361
|
+
if is_list(data):
|
|
362
|
+
return data
|
|
363
|
+
return list(data)
|
|
364
|
+
|
|
335
365
|
return [await _async_transform_recursive(d, annotation=annotation, inner_type=inner_type) for d in data]
|
|
336
366
|
|
|
337
367
|
if is_union_type(stripped_type):
|
|
@@ -393,6 +423,11 @@ async def _async_transform_typeddict(
|
|
|
393
423
|
result: dict[str, object] = {}
|
|
394
424
|
annotations = get_type_hints(expected_type, include_extras=True)
|
|
395
425
|
for key, value in data.items():
|
|
426
|
+
if not is_given(value):
|
|
427
|
+
# we don't need to include `NotGiven` values here as they'll
|
|
428
|
+
# be stripped out before the request is sent anyway
|
|
429
|
+
continue
|
|
430
|
+
|
|
396
431
|
type_ = annotations.get(key)
|
|
397
432
|
if type_ is None:
|
|
398
433
|
# we do not have a type annotation for this field, leave it as is
|
|
@@ -400,3 +435,13 @@ async def _async_transform_typeddict(
|
|
|
400
435
|
else:
|
|
401
436
|
result[_maybe_transform_key(key, type_)] = await _async_transform_recursive(value, annotation=type_)
|
|
402
437
|
return result
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
@lru_cache(maxsize=8096)
|
|
441
|
+
def get_type_hints(
|
|
442
|
+
obj: Any,
|
|
443
|
+
globalns: dict[str, Any] | None = None,
|
|
444
|
+
localns: Mapping[str, Any] | None = None,
|
|
445
|
+
include_extras: bool = False,
|
|
446
|
+
) -> dict[str, Any]:
|
|
447
|
+
return _get_type_hints(obj, globalns=globalns, localns=localns, include_extras=include_extras)
|
raccoonai/_utils/_typing.py
CHANGED
|
@@ -13,6 +13,7 @@ from typing_extensions import (
|
|
|
13
13
|
get_origin,
|
|
14
14
|
)
|
|
15
15
|
|
|
16
|
+
from ._utils import lru_cache
|
|
16
17
|
from .._types import InheritsGeneric
|
|
17
18
|
from .._compat import is_union as _is_union
|
|
18
19
|
|
|
@@ -66,6 +67,7 @@ def is_type_alias_type(tp: Any, /) -> TypeIs[typing_extensions.TypeAliasType]:
|
|
|
66
67
|
|
|
67
68
|
|
|
68
69
|
# Extracts T from Annotated[T, ...] or from Required[Annotated[T, ...]]
|
|
70
|
+
@lru_cache(maxsize=8096)
|
|
69
71
|
def strip_annotated_type(typ: type) -> type:
|
|
70
72
|
if is_required_type(typ) or is_annotated_type(typ):
|
|
71
73
|
return strip_annotated_type(cast(type, get_args(typ)[0]))
|
|
@@ -108,7 +110,7 @@ def extract_type_var_from_base(
|
|
|
108
110
|
```
|
|
109
111
|
"""
|
|
110
112
|
cls = cast(object, get_origin(typ) or typ)
|
|
111
|
-
if cls in generic_bases:
|
|
113
|
+
if cls in generic_bases: # pyright: ignore[reportUnnecessaryContains]
|
|
112
114
|
# we're given the class directly
|
|
113
115
|
return extract_type_arg(typ, index)
|
|
114
116
|
|
raccoonai/_utils/_utils.py
CHANGED
|
@@ -72,8 +72,16 @@ def _extract_items(
|
|
|
72
72
|
from .._files import assert_is_file_content
|
|
73
73
|
|
|
74
74
|
# We have exhausted the path, return the entry we found.
|
|
75
|
-
assert_is_file_content(obj, key=flattened_key)
|
|
76
75
|
assert flattened_key is not None
|
|
76
|
+
|
|
77
|
+
if is_list(obj):
|
|
78
|
+
files: list[tuple[str, FileTypes]] = []
|
|
79
|
+
for entry in obj:
|
|
80
|
+
assert_is_file_content(entry, key=flattened_key + "[]" if flattened_key else "")
|
|
81
|
+
files.append((flattened_key + "[]", cast(FileTypes, entry)))
|
|
82
|
+
return files
|
|
83
|
+
|
|
84
|
+
assert_is_file_content(obj, key=flattened_key)
|
|
77
85
|
return [(flattened_key, cast(FileTypes, obj))]
|
|
78
86
|
|
|
79
87
|
index += 1
|
raccoonai/_version.py
CHANGED
|
@@ -7,12 +7,7 @@ from typing import Mapping, cast
|
|
|
7
7
|
import httpx
|
|
8
8
|
|
|
9
9
|
from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven, FileTypes
|
|
10
|
-
from ..._utils import
|
|
11
|
-
extract_files,
|
|
12
|
-
maybe_transform,
|
|
13
|
-
deepcopy_minimal,
|
|
14
|
-
async_maybe_transform,
|
|
15
|
-
)
|
|
10
|
+
from ..._utils import extract_files, maybe_transform, deepcopy_minimal, async_maybe_transform
|
|
16
11
|
from ..._compat import cached_property
|
|
17
12
|
from ..._resource import SyncAPIResource, AsyncAPIResource
|
|
18
13
|
from ..._response import (
|
|
@@ -8,10 +8,7 @@ from typing_extensions import Literal
|
|
|
8
8
|
import httpx
|
|
9
9
|
|
|
10
10
|
from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven
|
|
11
|
-
from ..._utils import
|
|
12
|
-
maybe_transform,
|
|
13
|
-
async_maybe_transform,
|
|
14
|
-
)
|
|
11
|
+
from ..._utils import maybe_transform, async_maybe_transform
|
|
15
12
|
from ..._compat import cached_property
|
|
16
13
|
from ..._resource import SyncAPIResource, AsyncAPIResource
|
|
17
14
|
from ..._response import (
|
raccoonai/resources/lam/lam.py
CHANGED
|
@@ -17,11 +17,7 @@ from .tasks import (
|
|
|
17
17
|
)
|
|
18
18
|
from ...types import lam_run_params
|
|
19
19
|
from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven
|
|
20
|
-
from ..._utils import
|
|
21
|
-
required_args,
|
|
22
|
-
maybe_transform,
|
|
23
|
-
async_maybe_transform,
|
|
24
|
-
)
|
|
20
|
+
from ..._utils import required_args, maybe_transform, async_maybe_transform
|
|
25
21
|
from ..._compat import cached_property
|
|
26
22
|
from ..._resource import SyncAPIResource, AsyncAPIResource
|
|
27
23
|
from ..._response import (
|
|
@@ -266,7 +262,7 @@ class LamResource(SyncAPIResource):
|
|
|
266
262
|
"schema": schema,
|
|
267
263
|
"stream": stream,
|
|
268
264
|
},
|
|
269
|
-
lam_run_params.
|
|
265
|
+
lam_run_params.LamRunParamsStreaming if stream else lam_run_params.LamRunParamsNonStreaming,
|
|
270
266
|
),
|
|
271
267
|
options=make_request_options(
|
|
272
268
|
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
@@ -506,7 +502,7 @@ class AsyncLamResource(AsyncAPIResource):
|
|
|
506
502
|
"schema": schema,
|
|
507
503
|
"stream": stream,
|
|
508
504
|
},
|
|
509
|
-
lam_run_params.
|
|
505
|
+
lam_run_params.LamRunParamsStreaming if stream else lam_run_params.LamRunParamsNonStreaming,
|
|
510
506
|
),
|
|
511
507
|
options=make_request_options(
|
|
512
508
|
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
raccoonai/resources/lam/tasks.py
CHANGED
|
@@ -8,10 +8,7 @@ from typing_extensions import Literal
|
|
|
8
8
|
import httpx
|
|
9
9
|
|
|
10
10
|
from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven
|
|
11
|
-
from ..._utils import
|
|
12
|
-
maybe_transform,
|
|
13
|
-
async_maybe_transform,
|
|
14
|
-
)
|
|
11
|
+
from ..._utils import maybe_transform, async_maybe_transform
|
|
15
12
|
from ..._compat import cached_property
|
|
16
13
|
from ..._resource import SyncAPIResource, AsyncAPIResource
|
|
17
14
|
from ..._response import (
|
raccoonai/resources/tail/apps.py
CHANGED
|
@@ -5,10 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import httpx
|
|
6
6
|
|
|
7
7
|
from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven
|
|
8
|
-
from ..._utils import
|
|
9
|
-
maybe_transform,
|
|
10
|
-
async_maybe_transform,
|
|
11
|
-
)
|
|
8
|
+
from ..._utils import maybe_transform, async_maybe_transform
|
|
12
9
|
from ..._compat import cached_property
|
|
13
10
|
from ..._resource import SyncAPIResource, AsyncAPIResource
|
|
14
11
|
from ..._response import (
|
|
@@ -8,10 +8,7 @@ from typing_extensions import Literal
|
|
|
8
8
|
import httpx
|
|
9
9
|
|
|
10
10
|
from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven
|
|
11
|
-
from ..._utils import
|
|
12
|
-
maybe_transform,
|
|
13
|
-
async_maybe_transform,
|
|
14
|
-
)
|
|
11
|
+
from ..._utils import maybe_transform, async_maybe_transform
|
|
15
12
|
from ..._compat import cached_property
|
|
16
13
|
from ..._resource import SyncAPIResource, AsyncAPIResource
|
|
17
14
|
from ..._response import (
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: raccoonai
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0a17
|
|
4
4
|
Summary: The official Python library for the raccoonAI API
|
|
5
5
|
Project-URL: Homepage, https://github.com/raccoonaihq/raccoonai-python
|
|
6
6
|
Project-URL: Repository, https://github.com/raccoonaihq/raccoonai-python
|
|
@@ -177,7 +177,7 @@ print(response.advanced)
|
|
|
177
177
|
|
|
178
178
|
## File uploads
|
|
179
179
|
|
|
180
|
-
Request parameters that correspond to file uploads can be passed as `bytes`, a [`PathLike`](https://docs.python.org/3/library/os.html#os.PathLike) instance or a tuple of `(filename, contents, media type)`.
|
|
180
|
+
Request parameters that correspond to file uploads can be passed as `bytes`, or a [`PathLike`](https://docs.python.org/3/library/os.html#os.PathLike) instance or a tuple of `(filename, contents, media type)`.
|
|
181
181
|
|
|
182
182
|
```python
|
|
183
183
|
from pathlib import Path
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
raccoonai/__init__.py,sha256=ut5jCAExi9IzT9pzrjpsJoVhn6bzWI6jIXNXB-fXBY4,2523
|
|
2
|
-
raccoonai/_base_client.py,sha256=
|
|
3
|
-
raccoonai/_client.py,sha256
|
|
2
|
+
raccoonai/_base_client.py,sha256=_4wTEgzlmFDSwSH0b-KYmeYbSRVzw28FfeVPCW45mUo,64847
|
|
3
|
+
raccoonai/_client.py,sha256=b4Du_3dCdsg2TTDuMwokhvEDTrn5CWy5bqcsubr2ZaY,18886
|
|
4
4
|
raccoonai/_compat.py,sha256=VWemUKbj6DDkQ-O4baSpHVLJafotzeXmCQGJugfVTIw,6580
|
|
5
5
|
raccoonai/_constants.py,sha256=FkmVVcfVS3gR69v_fTrqA_qjakyxJHOWJcw3jpEck8Y,465
|
|
6
6
|
raccoonai/_exceptions.py,sha256=Y-DcD2M8xkSw8IEkk4KHj73O8GQxCtWm4HWYQ02j7z8,3226
|
|
7
7
|
raccoonai/_files.py,sha256=a0SHeBu6FT5rt_CKotWZyna5GpgB42go35AUK5sEiD4,3624
|
|
8
|
-
raccoonai/_models.py,sha256=
|
|
8
|
+
raccoonai/_models.py,sha256=mB2r2VWQq49jG-F0RIXDrBxPp3v-Eg12wMOtVTNxtv4,29057
|
|
9
9
|
raccoonai/_qs.py,sha256=AOkSz4rHtK4YI3ZU_kzea-zpwBUgEY8WniGmTPyEimc,4846
|
|
10
10
|
raccoonai/_resource.py,sha256=zfxyYCvzutc1dvCP-j9UPc1sn9U8F-X9gGyqleOvCxY,1118
|
|
11
|
-
raccoonai/_response.py,sha256=
|
|
11
|
+
raccoonai/_response.py,sha256=RuSNonzoPj-1q1FxDHtgUIMLvTqKLTg8GtTxrNV3XzY,28806
|
|
12
12
|
raccoonai/_streaming.py,sha256=zHnkREZO5v33YJ7P0YZ7KhJET4ZzevGw1JzRY2-Mls4,10112
|
|
13
13
|
raccoonai/_types.py,sha256=sN2zE-vBl9KBlBKL8fkN2DNZnItdjDl-3fTpP9cg69w,6146
|
|
14
|
-
raccoonai/_version.py,sha256
|
|
14
|
+
raccoonai/_version.py,sha256=-4VebHqdGC83aHpDGnNl7cMy5RMFsTh4VTwZnBUJ5cg,170
|
|
15
15
|
raccoonai/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
16
|
raccoonai/_utils/__init__.py,sha256=PNZ_QJuzZEgyYXqkO1HVhGkj5IU9bglVUcw7H-Knjzw,2062
|
|
17
17
|
raccoonai/_utils/_logs.py,sha256=Af3FKkE-LAPzYTl8bnFD4yPvPBIO-QyCra-r9_dSmOM,784
|
|
@@ -19,35 +19,35 @@ raccoonai/_utils/_proxy.py,sha256=z3zsateHtb0EARTWKk8QZNHfPkqJbqwd1lM993LBwGE,19
|
|
|
19
19
|
raccoonai/_utils/_reflection.py,sha256=ZmGkIgT_PuwedyNBrrKGbxoWtkpytJNU1uU4QHnmEMU,1364
|
|
20
20
|
raccoonai/_utils/_streams.py,sha256=SMC90diFFecpEg_zgDRVbdR3hSEIgVVij4taD-noMLM,289
|
|
21
21
|
raccoonai/_utils/_sync.py,sha256=TpGLrrhRNWTJtODNE6Fup3_k7zrWm1j2RlirzBwre-0,2862
|
|
22
|
-
raccoonai/_utils/_transform.py,sha256=
|
|
23
|
-
raccoonai/_utils/_typing.py,sha256=
|
|
24
|
-
raccoonai/_utils/_utils.py,sha256=
|
|
22
|
+
raccoonai/_utils/_transform.py,sha256=n7kskEWz6o__aoNvhFoGVyDoalNe6mJwp-g7BWkdj88,15617
|
|
23
|
+
raccoonai/_utils/_typing.py,sha256=D0DbbNu8GnYQTSICnTSHDGsYXj8TcAKyhejb0XcnjtY,4602
|
|
24
|
+
raccoonai/_utils/_utils.py,sha256=ts4CiiuNpFiGB6YMdkQRh2SZvYvsl7mAF-JWHCcLDf4,12312
|
|
25
25
|
raccoonai/lib/.keep,sha256=wuNrz-5SXo3jJaJOJgz4vFHM41YH_g20F5cRQo0vLes,224
|
|
26
26
|
raccoonai/resources/__init__.py,sha256=J3rNFGIi-0n5C4uqUHDax-dZCtNhFxnz1_LiF1Hm498,1374
|
|
27
27
|
raccoonai/resources/fleet/__init__.py,sha256=vGB3Zi0TL72b8i88mnBm-evtTa2DMGqZAQhdfMis6tQ,1517
|
|
28
|
-
raccoonai/resources/fleet/extensions.py,sha256=
|
|
28
|
+
raccoonai/resources/fleet/extensions.py,sha256=xHaXfCLLki5dSHJNoZG0834X_efayg5uJBXDGw2Io6c,15297
|
|
29
29
|
raccoonai/resources/fleet/fleet.py,sha256=q8Ola3g7CQOMO0XQ9CDsQ0iG3n7FEnUe_4VJLGGlGfw,4818
|
|
30
|
-
raccoonai/resources/fleet/sessions.py,sha256=
|
|
30
|
+
raccoonai/resources/fleet/sessions.py,sha256=d-EmJr0PnmaxGuM2b7W7CVPWIDPj7LAxXCJGLMWq6vY,28527
|
|
31
31
|
raccoonai/resources/lam/__init__.py,sha256=Thj6eBm5r07sqkqyE9K1JGjNKyzgaodJLy-qNrfrCWc,950
|
|
32
|
-
raccoonai/resources/lam/lam.py,sha256=
|
|
33
|
-
raccoonai/resources/lam/tasks.py,sha256=
|
|
32
|
+
raccoonai/resources/lam/lam.py,sha256=9QYNhhYDX1wUn6DsRPgjqhx-ikpfhy_uGlqQGbAoeHM,22438
|
|
33
|
+
raccoonai/resources/lam/tasks.py,sha256=K71XB-13oyb9_6QODgGFDf1BmWtgUZR6DZrz1CdcS2w,12529
|
|
34
34
|
raccoonai/resources/tail/__init__.py,sha256=1iOxKP4PRjPGjU1ss2L_8YbwPZ_MIA5cnyFbyELeRoA,1387
|
|
35
|
-
raccoonai/resources/tail/apps.py,sha256=
|
|
35
|
+
raccoonai/resources/tail/apps.py,sha256=SqxIPZ6M-f9pZl0bJezFi2HhqecmZ14NIfti94OqkPM,7995
|
|
36
36
|
raccoonai/resources/tail/tail.py,sha256=L3HtDA-G4GSGdD5YjWp5IcjuYGINRFdua0-YKHrAavA,4517
|
|
37
|
-
raccoonai/resources/tail/users.py,sha256=
|
|
37
|
+
raccoonai/resources/tail/users.py,sha256=zlnmF5ycgv47dA3Zwj7ryADicsPw5pu3666kzmN7UgE,14490
|
|
38
38
|
raccoonai/types/__init__.py,sha256=zPr9s--p1dwMuN9TZf38xnrr_T0G8FA2LLIPUazW4FA,243
|
|
39
39
|
raccoonai/types/lam_run_params.py,sha256=WEz4-fSyhk72lke57m68n0ATFeiHwpOsaWvnguoz6yM,2733
|
|
40
40
|
raccoonai/types/lam_run_response.py,sha256=pOBB0xmGZou7vMG-dmhUk6v5pMyJF4dXWnNWXAHvfW0,891
|
|
41
41
|
raccoonai/types/fleet/__init__.py,sha256=4z1oeJkLJ-abdHCDxQ0lO9zOkpJXtSaR5qgVeVsaHLE,1101
|
|
42
42
|
raccoonai/types/fleet/extension_all_response.py,sha256=J9Y5qq3Eukik_0Bmyq75kLEhJJohJOF_Hx8vWUv_Sq8,527
|
|
43
|
-
raccoonai/types/fleet/extension_get_response.py,sha256=
|
|
43
|
+
raccoonai/types/fleet/extension_get_response.py,sha256=MXYmru1ocw_-VtUQHGKYU5wOJ6QST5NzXfwPxl4wb7w,397
|
|
44
44
|
raccoonai/types/fleet/extension_upload_params.py,sha256=UUR2H0DrvNgpLJfCTyO28Gv5xI8EEOEFErwmj3Ru5z0,328
|
|
45
|
-
raccoonai/types/fleet/extension_upload_response.py,sha256=
|
|
45
|
+
raccoonai/types/fleet/extension_upload_response.py,sha256=IDWmw40WxBfK8aZe2SgtZY4oEi-N1kSV7ZpjvCtdg24,403
|
|
46
46
|
raccoonai/types/fleet/session_all_params.py,sha256=8PmXYnnvdc52Hw4q4d0bzWMeeq_7m5LraRghHwI_wl0,1432
|
|
47
47
|
raccoonai/types/fleet/session_all_response.py,sha256=Z4_iJCGAtfFpYZTiBmYAZJaPzyVUfS1Qkwe5nEeuPcY,1721
|
|
48
48
|
raccoonai/types/fleet/session_create_params.py,sha256=1DK11wJV9XqXRRIHPuHMpusxQeg3ueM1a5NcAaQOoZA,2567
|
|
49
49
|
raccoonai/types/fleet/session_create_response.py,sha256=WbVwyfesj9QWuYEhDPoNji7U5eJmEOA44NmImWCl4qk,602
|
|
50
|
-
raccoonai/types/fleet/session_logs_response.py,sha256
|
|
50
|
+
raccoonai/types/fleet/session_logs_response.py,sha256=-Qzhml3YEMUFMbsTlFX8OqA0qPOX040CO3U4LaQlweU,364
|
|
51
51
|
raccoonai/types/fleet/session_media_response.py,sha256=FsE4vgxweb0y25J5YYa_fHbVy8IaQfstEZ90QIxVx3c,1118
|
|
52
52
|
raccoonai/types/fleet/session_status_response.py,sha256=bmmZk4f6aV3lS3ENILoLQm38dKVkVY4uN-H-OTUrxgM,432
|
|
53
53
|
raccoonai/types/fleet/session_terminate_response.py,sha256=UbA_9CwZOmRMcxqaNMIFNGA8pwpAY1fagb_2voYBQ0c,438
|
|
@@ -62,10 +62,10 @@ raccoonai/types/tail/app_linked_response.py,sha256=i7ox4Z5UsJhQMQm8DkB9YTz9chqNs
|
|
|
62
62
|
raccoonai/types/tail/user_all_params.py,sha256=SeS6QCT2HYtQnUFaptIcy2Fla01CQq0deno72yb8TS8,832
|
|
63
63
|
raccoonai/types/tail/user_all_response.py,sha256=J13hVLXOWD_S5AWs--i4fR73FUuiJ8cZQ9UoBIkPVRo,1227
|
|
64
64
|
raccoonai/types/tail/user_create_params.py,sha256=4Pe2d2L_TqNAeBNtG92ml1zLA3wTt_NE_6zJ-2YDtFY,370
|
|
65
|
-
raccoonai/types/tail/user_create_response.py,sha256=
|
|
65
|
+
raccoonai/types/tail/user_create_response.py,sha256=eYexuFeSkGZs58pqSLga-9D4zAwCEiX7xi6OllB3F2Q,517
|
|
66
66
|
raccoonai/types/tail/user_status_params.py,sha256=gxSN0_zGeqOSKpDaoKh0O6l8j0jMyxP7f7ONIPWOVZE,459
|
|
67
67
|
raccoonai/types/tail/user_status_response.py,sha256=BakDkr-yhueamBAx-wrHCUZ4h9rYJCQPnDD49paA_aU,472
|
|
68
|
-
raccoonai-0.1.
|
|
69
|
-
raccoonai-0.1.
|
|
70
|
-
raccoonai-0.1.
|
|
71
|
-
raccoonai-0.1.
|
|
68
|
+
raccoonai-0.1.0a17.dist-info/METADATA,sha256=B_AbRyMJYqIY-sq1YU0HsBKLoTigKuuB-GjySXGQzS4,15528
|
|
69
|
+
raccoonai-0.1.0a17.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
70
|
+
raccoonai-0.1.0a17.dist-info/licenses/LICENSE,sha256=enGvZ2fGU7wGgMPWkgyWhnsFhCpxwdeG_selO_ovoTM,11340
|
|
71
|
+
raccoonai-0.1.0a17.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|