Add RBI annotations for fields and params (#1559) (#1562)

* Introduce types to ruby

* rubocop

* forgot these files

* other request methods

* more tests, fix for raw request

* Add README entry for types

* rebase and regen
This commit is contained in:
helenye-stripe 2025-03-31 16:19:56 -07:00 committed by GitHub
commit a6c600a871
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 114 additions and 0 deletions

View File

@ -317,6 +317,35 @@ You can disable this behavior if you prefer:
Stripe.enable_telemetry = false Stripe.enable_telemetry = false
``` ```
### Types
In [v14.0.0](https://github.com/stripe/stripe-python/releases/tag/v7.1.0) and newer, the library provides RBI
static type annotations. See [the wiki](https://github.com/stripe/stripe-ruby/wiki/Static-Type-Annotations)
for an detailed guide.
Please note that these types are available only for static analysis and we only support RBIs at the moment.
Please [report an issue](https://github.com/stripe/stripe-ruby/issues/new/choose)
if you find discrepancies or have issues using types.
The RBIs can be found in the `rbi/stripe/` directory, and to decrease `Tapioca` loading time we pack the gem with the
combined RBI at `rbi/stripe.rbi`.
#### Types and the Versioning Policy
We release type changes in minor releases. While stripe-ruby follows semantic versioning, our semantic
versions describe the runtime behavior of the library alone. Our type annotations are not reflected in the
semantic version. That is, upgrading to a new minor version of `stripe-ruby` might result in your type checker
producing a type error that it didn't before. You can use `~> x.x` or `x.x.x` constrain the version
of `stripe-ruby` in your Gemfile to a certain version or range of `stripe-ruby`.
#### Types and API Versions
The types describe the [Stripe API version](https://stripe.com/docs/api/versioning)
that was the latest at the time of release. This is the version that your library sends
by default. If you are overriding `Stripe.api_version` / `stripe_version` on the StripeClient,
or using a webhook endpoint tied to an older version, be aware that the data
you see at runtime may not match the types.
### Beta SDKs ### Beta SDKs
Stripe has features in the beta phase that can be accessed via the beta version of this package. Stripe has features in the beta phase that can be accessed via the beta version of this package.

View File

@ -222,6 +222,7 @@ module Stripe
params: {}, opts: {}, usage: []) params: {}, opts: {}, usage: [])
opts = RequestOptions.combine_opts(object.instance_variable_get(:@opts), opts) opts = RequestOptions.combine_opts(object.instance_variable_get(:@opts), opts)
opts = Util.normalize_opts(opts) opts = Util.normalize_opts(opts)
params = params.to_h if params.is_a?(RequestParams)
http_resp, req_opts = execute_request_internal( http_resp, req_opts = execute_request_internal(
method, path, base_address, params, opts, usage method, path, base_address, params, opts, usage
) )
@ -271,6 +272,7 @@ module Stripe
"execute_request_stream requires a read_body_chunk_block" "execute_request_stream requires a read_body_chunk_block"
end end
params = params.to_h if params.is_a?(RequestParams)
http_resp, api_key = execute_request_internal( http_resp, api_key = execute_request_internal(
method, path, base_address, params, opts, usage, &read_body_chunk_block method, path, base_address, params, opts, usage, &read_body_chunk_block
) )

View File

@ -74,6 +74,7 @@ module Stripe
opts = Util.normalize_opts(opts) opts = Util.normalize_opts(opts)
req_opts = RequestOptions.extract_opts_from_hash(opts) req_opts = RequestOptions.extract_opts_from_hash(opts)
params = params.to_h if params.is_a?(Stripe::RequestParams)
resp, = @requestor.send(:execute_request_internal, method, url, base_address, params, req_opts, usage: ["raw_request"]) resp, = @requestor.send(:execute_request_internal, method, url, base_address, params, req_opts, usage: ["raw_request"])
@requestor.interpret_response(resp) @requestor.interpret_response(resp)

View File

@ -51,5 +51,87 @@ module Stripe
assert cus.is_a?(Stripe::Customer) assert cus.is_a?(Stripe::Customer)
end end
end end
context "different request types" do
should "create a customer with params class" do
stub_request(:post, "#{Stripe.api_base}/v1/customers")
.with(body: "name=foo")
.to_return(body: JSON.generate(object: "customer", id: "cus_123", name: "foo"))
params = Stripe::Customer::CreateParams.new(name: "foo")
customer = Stripe::Customer.create(params)
assert customer.is_a?(Stripe::Customer)
assert_equal "cus_123", customer.id
assert_equal "foo", customer.name
end
should "update a customer with params class" do
stub_request(:post, "#{Stripe.api_base}/v1/customers/cus_123")
.with(body: "name=bar")
.to_return(body: JSON.generate(object: "customer", id: "cus_123", name: "bar"))
params = Stripe::Customer::UpdateParams.new(name: "bar")
customer = Stripe::Customer.update("cus_123", params)
assert customer.is_a?(Stripe::Customer)
assert_equal "cus_123", customer.id
assert_equal "bar", customer.name
end
# NOTE: Resource-based retrieve expand is a special case...
should "retrieve a customer with params class" do
stub_request(:get, "#{Stripe::DEFAULT_API_BASE}/v1/customers/cus_123?expand[]=foo")
.to_return(body: JSON.generate(object: "customer", id: "cus_123", name: "foo"))
@client = Stripe::StripeClient.new("sk_test_123")
customer = @client.v1.customers.retrieve("cus_123", CustomerService::RetrieveParams.new(expand: [:foo]))
assert customer.is_a?(Stripe::Customer)
end
should "list customers with params class" do
stub_request(:get, "#{Stripe.api_base}/v1/customers")
.to_return(body: JSON.generate(object: "list", data: [{ id: "cus_123", name: "foo" }, { id: "cus_456", name: "bar" }]))
customers = Stripe::Customer.list
assert customers.is_a?(Stripe::ListObject)
assert_equal 2, customers.data.size
assert_equal "cus_123", customers.data[0].id
assert_equal "foo", customers.data[0].name
assert_equal "cus_456", customers.data[1].id
assert_equal "bar", customers.data[1].name
end
should "search customers with params class" do
stub_request(:get, "#{Stripe.api_base}/v1/customers/search")
.with(query: { query: "name:'foo'" })
.to_return(body: JSON.generate(object: "search_result", data: [{ id: "cus_123", name: "foo" }]))
params = Stripe::Customer::SearchParams.new(query: "name:'foo'")
customers = Stripe::Customer.search(params)
assert customers.is_a?(Stripe::SearchResultObject)
assert_equal 1, customers.data.size
assert_equal "cus_123", customers.data[0].id
assert_equal "foo", customers.data[0].name
end
should "request params work in raw request" do
expected_body = JSON.generate(id: "cus_123", name: "foo")
req = nil
stub_request(:post, "#{Stripe::DEFAULT_API_BASE}/v1/customers")
.with(body: "name=foo")
.with { |request| req = request }
.to_return(body: expected_body)
@client = Stripe::StripeClient.new("sk_test_123")
resp = @client.raw_request(:post, "/v1/customers", params: Customer::CreateParams.new(name: "foo"))
assert_equal expected_body, resp.http_body
end
end
end end
end end