Skip to content

Commit

Permalink
raw_request_async
Browse files Browse the repository at this point in the history
  • Loading branch information
richardm-stripe committed Dec 8, 2023
1 parent 68fd7dc commit 288a34a
Show file tree
Hide file tree
Showing 10 changed files with 606 additions and 97 deletions.
4 changes: 4 additions & 0 deletions stripe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
verify_ssl_certs: bool = True
proxy: Optional[str] = None
default_http_client: Optional["HTTPClient"] = None
default_http_client_async: Optional["HTTPClientAsync"] = None
app_info: Optional[AppInfo] = None
enable_telemetry: bool = True
max_network_retries: int = 0
Expand All @@ -47,6 +48,7 @@
WebhookSignature as WebhookSignature,
)
from stripe._raw_request import raw_request as raw_request # noqa
from stripe._raw_request import raw_request_async as raw_request_async # noqa
from stripe._raw_request import deserialize as deserialize # noqa

from stripe._preview import preview as preview # noqa
Expand Down Expand Up @@ -141,9 +143,11 @@ def set_app_info(
# HttpClient
from stripe._http_client import (
HTTPClient as HTTPClient,
HTTPClientAsync as HTTPClientAsync,
PycurlClient as PycurlClient,
RequestsClient as RequestsClient,
UrlFetchClient as UrlFetchClient,
HTTPXClient as HTTPXClient,
new_default_http_client as new_default_http_client,
)

Expand Down
118 changes: 116 additions & 2 deletions stripe/_api_requestor.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
Optional,
Tuple,
cast,
Union,
)
from typing_extensions import NoReturn, Literal
import uuid
Expand Down Expand Up @@ -77,6 +78,16 @@ def __init__(
self._client = stripe.default_http_client
self._default_proxy = proxy

if stripe.default_http_client_async:
self._client_async = stripe.default_http_client_async
else:
stripe.default_http_client_async = (
_http_client.new_default_http_client_async(
verify_ssl_certs=verify, proxy=proxy
)
)
self._client_async = stripe.default_http_client_async

@classmethod
def format_app_info(cls, info):
str = info["name"]
Expand Down Expand Up @@ -105,6 +116,25 @@ def request(
resp = self.interpret_response(rbody, rcode, rheaders)
return resp, my_api_key

async def request_async(
self,
method: str,
url: str,
params: Optional[Mapping[str, Any]] = None,
headers: Optional[Mapping[str, str]] = None,
api_mode: Optional[Literal["preview", "standard"]] = None,
) -> Tuple[StripeResponse, str]:
rbody, rcode, rheaders, my_api_key = await self.request_raw_async(
method.lower(),
url,
params,
headers,
is_streaming=False,
api_mode=api_mode,
)
resp = self.interpret_response(rbody, rcode, rheaders)
return resp, my_api_key

def request_stream(
self,
method: str,
Expand All @@ -130,6 +160,31 @@ def request_stream(
)
return resp, my_api_key

async def request_stream_async(
self,
method: str,
url: str,
params: Optional[Mapping[str, Any]] = None,
headers: Optional[Mapping[str, str]] = None,
api_mode: Optional[Literal["preview", "standard"]] = None,
) -> Tuple[StripeStreamResponse, str]:
stream, rcode, rheaders, my_api_key = await self.request_raw_async(
method.lower(),
url,
params,
headers,
is_streaming=True,
api_mode=api_mode,
)
resp = self.interpret_streaming_response(
# TODO: should be able to remove this cast once self._client.request_stream_with_retries
# returns a more specific type.
cast(IOBase, stream),
rcode,
rheaders,
)
return resp, my_api_key

def handle_error_response(self, rbody, rcode, resp, rheaders) -> NoReturn:
try:
error_data = resp["error"]
Expand Down Expand Up @@ -305,15 +360,15 @@ def request_headers(self, api_key, method, api_mode) -> Dict[str, str]:

return headers

def request_raw(
def _get_request_raw_args(
self,
method: str,
url: str,
params: Optional[Mapping[str, Any]] = None,
supplied_headers: Optional[Mapping[str, str]] = None,
is_streaming: bool = False,
api_mode: Optional[Literal["preview", "standard"]] = None,
) -> Tuple[object, int, Mapping[str, str], str]:
) -> Tuple[str, Dict[str, str], Optional[Union[bytes, str]], str]:
"""
Mechanism for issuing an API call
"""
Expand Down Expand Up @@ -391,6 +446,21 @@ def request_raw(
api_version=self.api_version,
)

return abs_url, headers, post_data, my_api_key

def request_raw(
self,
method: str,
url: str,
params: Optional[Mapping[str, Any]] = None,
supplied_headers: Optional[Mapping[str, str]] = None,
is_streaming: bool = False,
api_mode: Optional[Literal["preview", "standard"]] = None,
) -> Tuple[object, int, Mapping[str, str], str]:
abs_url, headers, post_data, my_api_key = self._get_request_raw_args(
method, url, params, supplied_headers, is_streaming, api_mode
)

if is_streaming:
(
rcontent,
Expand Down Expand Up @@ -418,6 +488,50 @@ def request_raw(

return rcontent, rcode, rheaders, my_api_key

async def request_raw_async(
self,
method: str,
url: str,
params: Optional[Mapping[str, Any]] = None,
supplied_headers: Optional[Mapping[str, str]] = None,
is_streaming: bool = False,
api_mode: Optional[Literal["preview", "standard"]] = None,
) -> Tuple[object, int, Mapping[str, str], str]:
abs_url, headers, post_data, my_api_key = self._get_request_raw_args(
method, url, params, supplied_headers, is_streaming, api_mode
)

if is_streaming:
(
rcontent,
rcode,
rheaders,
) = await self._client_async.request_stream_with_retries(
method, abs_url, headers, post_data
)
else:
(
rcontent,
rcode,
rheaders,
) = await self._client_async.request_with_retries(
method, abs_url, headers, post_data
)

_util.log_info(
"Stripe API response", path=abs_url, response_code=rcode
)
_util.log_debug("API response body", body=rcontent)

if "Request-Id" in rheaders:
request_id = rheaders["Request-Id"]
_util.log_debug(
"Dashboard link for request",
link=_util.dashboard_link(request_id),
)

return rcontent, rcode, rheaders, my_api_key

def _should_handle_code_as_error(self, rcode):
return not 200 <= rcode < 300

Expand Down
Loading

0 comments on commit 288a34a

Please sign in to comment.