Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moved raw_request functions from stripe module to StripeClient class #1390

Open
wants to merge 7 commits into
base: beta
Choose a base branch
from
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,15 +266,16 @@ stripe.add_beta_version("feature_beta", "v3")

### Custom requests

If you would like to send a request to an undocumented API (for example you are in a private beta), or if you prefer to bypass the method definitions in the library and specify your request details directly, you can use the `raw_request` method on `stripe`.
If you would like to send a request to an undocumented API (for example you are in a private beta), or if you prefer to bypass the method definitions in the library and specify your request details directly, you can use the `raw_request` method on `StripeClient`.

```python
response = stripe.raw_request(
client = StripeClient("sk_test_...")
response = client.raw_request(
"post", "/v1/beta_endpoint", param=123, stripe_version="2022-11-15; feature_beta=v3"
)

# (Optional) response is a StripeResponse. You can use `stripe.deserialize` to get a StripeObject.
deserialized_resp = stripe.deserialize(response)
# (Optional) response is a StripeResponse. You can use `deserialize` on `StripeClient` to get a StripeObject.
deserialized_resp = client.deserialize(response)
```

### Async
Expand Down
5 changes: 0 additions & 5 deletions stripe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,6 @@
Webhook as Webhook,
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

# StripeClient
from stripe._stripe_client import StripeClient as StripeClient # noqa
Expand Down
2 changes: 1 addition & 1 deletion stripe/_api_requestor.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ def _args_for_request_with_retries(
usage: Optional[List[str]] = None,
):
"""
Mechanism for issuing an API call
Mechanism for issuing an API call. Used by request_raw and request_raw_async.
"""
request_options = merge_options(self._options, options)

Expand Down
31 changes: 0 additions & 31 deletions stripe/_preview.py

This file was deleted.

80 changes: 0 additions & 80 deletions stripe/_raw_request.py

This file was deleted.

69 changes: 66 additions & 3 deletions stripe/_stripe_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from stripe._error import AuthenticationError
from stripe._api_requestor import _APIRequestor
from stripe._request_options import extract_options_from_dict
from stripe._requestor_options import RequestorOptions, BaseAddresses
from stripe._client_options import _ClientOptions
from stripe._http_client import (
Expand All @@ -19,10 +20,13 @@
new_http_client_async_fallback,
)
from stripe._api_version import _ApiVersion
from stripe._stripe_object import StripeObject
from stripe._stripe_response import StripeResponse
from stripe._util import _convert_to_stripe_object
from stripe._webhook import Webhook, WebhookSignature
from stripe._event import Event

from typing import Optional, Union, cast
from typing import Any, Dict, Optional, Union, cast

# Non-generated services
from stripe._oauth_service import OAuthService
Expand Down Expand Up @@ -146,7 +150,7 @@ def __init__(
**base_addresses,
}

requestor_options = RequestorOptions(
self._requestor_options = RequestorOptions(
ramya-stripe marked this conversation as resolved.
Show resolved Hide resolved
api_key=api_key,
stripe_account=stripe_account,
stripe_version=stripe_version or _ApiVersion.CURRENT,
Expand All @@ -164,7 +168,7 @@ def __init__(
)

self._requestor = _APIRequestor(
options=requestor_options,
options=self._requestor_options,
client=http_client,
)

Expand Down Expand Up @@ -280,3 +284,62 @@ def construct_event(
)

return event

def raw_request(self, method_: str, url_: str, **params):
params = params.copy()
options, params = extract_options_from_dict(params)
api_mode = params.pop("api_mode", None)
base_address = params.pop("base", "api")

stripe_context = params.pop("stripe_context", None)

# stripe-context goes *here* and not in api_requestor. Properties
# go on api_requestor when you want them to persist onto requests
# made when you call instance methods on APIResources that come from
# the first request. No need for that here, as we aren't deserializing APIResources
if stripe_context is not None:
options["headers"] = options.get("headers", {})
assert isinstance(options["headers"], dict)
options["headers"].update({"Stripe-Context": stripe_context})

rbody, rcode, rheaders = self._requestor.request_raw(
method_,
url_,
params=params,
options=options,
base_address=base_address,
api_mode=api_mode,
usage=["raw_request"],
)

return self._requestor._interpret_response(rbody, rcode, rheaders)

async def raw_request_async(self, method_: str, url_: str, **params):
params = params.copy()
options, params = extract_options_from_dict(params)
api_mode = params.pop("api_mode", None)
base_address = params.pop("base", "api")

rbody, rcode, rheaders = await self._requestor.request_raw_async(
method_,
url_,
params=params,
options=options,
base_address=base_address,
api_mode=api_mode,
usage=["raw_request"],
)

return self._requestor._interpret_response(rbody, rcode, rheaders)

def deserialize(
self,
resp: Union[StripeResponse, Dict[str, Any]],
params: Optional[Dict[str, Any]] = None,
) -> StripeObject:
return _convert_to_stripe_object(
resp=resp,
params=params,
requestor=self._requestor,
api_mode="V1",
)
45 changes: 34 additions & 11 deletions tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from collections import defaultdict
from typing import List, Dict, Tuple, Optional

from stripe._stripe_client import StripeClient

if platform.python_implementation() == "PyPy":
pytest.skip("skip integration tests with PyPy", allow_module_level=True)

Expand Down Expand Up @@ -359,12 +361,16 @@ class MockServerRequestHandler(MyTestHandler):

self.setup_mock_server(MockServerRequestHandler)

stripe.api_base = "http://localhost:%s" % self.mock_server_port

resp = await stripe.raw_request_async(
client = StripeClient(
"sk_test_123",
base_addresses={
"api": "http://localhost:%s" % self.mock_server_port
},
)
resp = await client.raw_request_async(
"post", "/v1/customers", description="My test customer"
)
cus = stripe.deserialize(resp.data)
cus = client.deserialize(resp.data)

reqs = MockServerRequestHandler.get_requests(1)
req = reqs[0]
Expand All @@ -382,7 +388,6 @@ def do_request(self, n):
return super().do_request(n)

self.setup_mock_server(MockServerRequestHandler)
stripe.api_base = "http://localhost:%s" % self.mock_server_port
# If we set HTTPX's generic timeout the test is flaky (sometimes it's a ReadTimeout, sometimes its a ConnectTimeout)
# so we set only the read timeout specifically.
hc = stripe.default_http_client
Expand All @@ -396,11 +401,18 @@ def do_request(self, n):
expected_message = "A ServerTimeoutError was raised"
else:
raise ValueError(f"Unknown http client: {hc.name}")
stripe.max_network_retries = 0

exception = None
try:
await stripe.raw_request_async(
client = StripeClient(
"sk_test_123",
http_client=hc,
base_addresses={
"api": "http://localhost:%s" % self.mock_server_port
},
max_network_retries=0,
)
await client.raw_request_async(
"post", "/v1/customers", description="My test customer"
)
except stripe.APIConnectionError as e:
Expand All @@ -426,9 +438,15 @@ def do_request(self, n):
pass

self.setup_mock_server(MockServerRequestHandler)
stripe.api_base = "http://localhost:%s" % self.mock_server_port

await stripe.raw_request_async(
client = StripeClient(
"sk_test_123",
base_addresses={
"api": "http://localhost:%s" % self.mock_server_port
},
max_network_retries=stripe.max_network_retries,
)
await client.raw_request_async(
"post", "/v1/customers", description="My test customer"
)

Expand All @@ -451,11 +469,16 @@ def do_request(self, n):
pass

self.setup_mock_server(MockServerRequestHandler)
stripe.api_base = "http://localhost:%s" % self.mock_server_port

exception = None
try:
await stripe.raw_request_async(
client = StripeClient(
"sk_test_123",
base_addresses={
"api": "http://localhost:%s" % self.mock_server_port
},
)
await client.raw_request_async(
"post", "/v1/customers", description="My test customer"
)
except stripe.AuthenticationError as e:
Expand Down
Loading
Loading