Skip to content

Commit

Permalink
Support for APIs in the new API version 2024-09-30.acacia (#1458)
Browse files Browse the repository at this point in the history
  • Loading branch information
ramya-stripe authored Oct 1, 2024
1 parent 07ee576 commit 39d8736
Show file tree
Hide file tree
Showing 256 changed files with 17,774 additions and 3,166 deletions.
26 changes: 25 additions & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@ Layout/FirstHashElementIndentation:
Layout/LineLength:
Exclude:
- "lib/stripe/object_types.rb"
- "lib/stripe/stripe_client.rb"
- "lib/stripe/resources/**/*.rb"
- "lib/stripe/services/**/*.rb"
- "test/**/*.rb"

Metrics/AbcSize:
Enabled: false

Metrics/BlockLength:
Max: 40
Exclude:
Expand All @@ -29,18 +34,37 @@ Metrics/BlockLength:
Metrics/ClassLength:
Enabled: false

# There are several methods with many branches in api_requestor due to
# request logic.
Metrics/CyclomaticComplexity:
Exclude:
- "lib/stripe/api_requestor.rb"
- "lib/stripe/util.rb"

Metrics/PerceivedComplexity:
Exclude:
- "lib/stripe/api_requestor.rb"
- "lib/stripe/util.rb"

Metrics/MethodLength:
# There's ~2 long methods in `StripeClient` and one in `NestedResource`. If
# There's ~2 long methods in `APIRequestor` and one in `NestedResource`. If
# we want to truncate those a little, we could move this to be closer to ~30
# (but the default of 10 is probably too short).
Max: 55
Exclude:
- "lib/stripe/services/v1_services.rb"

Metrics/ModuleLength:
Enabled: false

Metrics/ParameterLists:
# There's 2 methods in `StripeClient` that have long parameter lists.
Max: 8
# Optional parameters should be consistent across libraries, we need not be
# concerned about this. Was introduced with adding `base_address`
Exclude:
- "lib/stripe/api_operations/request.rb"
- "lib/stripe/stripe_object.rb"

Style/AccessModifierDeclarations:
EnforcedStyle: inline
Expand Down
8 changes: 4 additions & 4 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# Offense count: 2
Lint/HashCompareByIdentity:
Exclude:
- 'lib/stripe/stripe_client.rb'
- 'lib/stripe/api_requestor.rb'

# Offense count: 26
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
Expand Down Expand Up @@ -47,7 +47,7 @@ Style/CaseLikeIf:
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/CombinableLoops:
Exclude:
- 'lib/stripe/stripe_client.rb'
- 'lib/stripe/api_requestor.rb'

# Offense count: 39
# Configuration parameters: AllowedConstants.
Expand All @@ -59,7 +59,7 @@ Style/Documentation:
# Configuration parameters: AllowSplatArgument.
Style/HashConversion:
Exclude:
- 'lib/stripe/stripe_client.rb'
- 'lib/stripe/api_requestor.rb'

# Offense count: 3
# This cop supports unsafe autocorrection (--autocorrect-all).
Expand All @@ -81,7 +81,7 @@ Style/StringConcatenation:
- 'lib/stripe/oauth.rb'
- 'lib/stripe/resources/bank_account.rb'
- 'lib/stripe/resources/source.rb'
- 'lib/stripe/stripe_client.rb'
- 'lib/stripe/api_requestor.rb'
- 'test/stripe/api_resource_test.rb'
- 'test/stripe/stripe_client_test.rb'
- 'test/stripe/webhook_test.rb'
2 changes: 1 addition & 1 deletion OPENAPI_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1255
v1268
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -346,13 +346,14 @@ If you:
- prefer to bypass the method definitions in the library and specify your request details directly,
- used the method `Stripe::APIResource.request(...)` to specify your own requests, which will soon be broken

you can now use the `raw_request` method on `Stripe`.
you can now use the `raw_request` method on `StripeClient`.

```ruby
resp = Stripe.raw_request(:post, "/v1/beta_endpoint", {param: 123}, {stripe_version: "2022-11-15; feature_beta=v3"})
client = Stripe::StripeClient.new(...)
resp = client.raw_request(:post, "/v1/beta_endpoint", {param: 123}, {stripe_version: "2022-11-15; feature_beta=v3"})
# (Optional) resp is a StripeResponse. You can use `Stripe.deserialize` to get a StripeObject.
deserialized_resp = Stripe.deserialize(resp.http_body)
deserialized_resp = client.deserialize(resp.http_body)
```

## Support
Expand Down
11 changes: 11 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## Running an example

From the examples folder, run:
`RUBYLIB=../lib ruby your_example.rb`

## Adding a new example

1. Clone new_example.rb
2. Implement your example
3. Run it (as per above)
4. 👍
47 changes: 47 additions & 0 deletions examples/meter_event_stream.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true

require "stripe"
require "date"

class MeterEventManager
attr_accessor :api_key, :meter_event_session

def initialize(api_key)
@api_key = api_key
@meter_event_session = nil
end

def refresh_meter_event_session
return unless @meter_event_session.nil? || DateTime.parse(@meter_event_session.expires_at) <= DateTime.now

# Create a new meter event session in case the existing session expired
client = Stripe::StripeClient.new(api_key)
@meter_event_session = client.v2.billing.meter_event_session.create
end

def send_meter_event(meter_event)
# Refresh the meter event session if necessary
refresh_meter_event_session

# Create a meter event with the current session's authentication token
client = Stripe::StripeClient.new(meter_event_session.authentication_token)
client.v2.billing.meter_event_stream.create(
events: [meter_event]
)
end
end

# Send meter events
api_key = "{{API_KEY}}"
customer_id = "{{CUSTOMER_ID}}"

manager = MeterEventManager.new(api_key)
manager.send_meter_event(
{
event_name: "alpaca_ai_tokens",
payload: {
"stripe_customer_id" => customer_id,
"value" => "25",
},
}
)
24 changes: 24 additions & 0 deletions examples/new_example.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

require "stripe"
require "date"

class NewExample
attr_accessor :api_key

def initialize(api_key)
@api_key = api_key
end

def do_something_great
puts "Hello World"
# client = Stripe::StripeClient.new(api_key)
# client.v1
end
end

# Send meter events
api_key = "{{API_KEY}}"

example = NewExample.new(api_key)
example.do_something_great
28 changes: 28 additions & 0 deletions examples/stripe_webhook_handler.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# frozen_string_literal: true
# typed: false

require "stripe"
require "sinatra"

api_key = ENV.fetch("STRIPE_API_KEY", nil)
# Retrieve the webhook secret from the environment variable
webhook_secret = ENV.fetch("WEBHOOK_SECRET", nil)

client = Stripe::StripeClient.new(api_key)

post "/webhook" do
webhook_body = request.body.read
sig_header = request.env["HTTP_STRIPE_SIGNATURE"]
thin_event = client.parse_thin_event(webhook_body, sig_header, webhook_secret)

# Fetch the event data to understand the failure
event = client.v2.core.events.retrieve(thin_event.id)
if event.instance_of? Stripe::V1BillingMeterErrorReportTriggeredEvent
meter = event.fetch_related_object
meter_id = meter.id
puts "Success!", meter_id
end

# Record the failures and alert your team
status 200
end
40 changes: 15 additions & 25 deletions lib/stripe.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,34 @@
# API resource support classes
require "stripe/errors"
require "stripe/object_types"
require "stripe/event_types"
require "stripe/request_options"
require "stripe/util"
require "stripe/connection_manager"
require "stripe/multipart_encoder"
require "stripe/api_requestor"
require "stripe/stripe_service"
require "stripe/stripe_client"
require "stripe/stripe_object"
require "stripe/stripe_response"
require "stripe/list_object"
require "stripe/v2_list_object"
require "stripe/search_result_object"
require "stripe/error_object"
require "stripe/api_resource"
require "stripe/api_resource_test_helpers"
require "stripe/singleton_api_resource"
require "stripe/webhook"
require "stripe/stripe_configuration"
require "stripe/thin_event"

# Named API resources
require "stripe/resources"
require "stripe/services"

# OAuth
require "stripe/oauth"
require "stripe/services/oauth_service"

module Stripe
DEFAULT_CA_BUNDLE_PATH = __dir__ + "/data/ca-certificates.crt"
Expand All @@ -60,6 +68,12 @@ module Stripe
LEVEL_ERROR = Logger::ERROR
LEVEL_INFO = Logger::INFO

# API base constants
DEFAULT_API_BASE = "https://api.stripe.com"
DEFAULT_CONNECT_BASE = "https://connect.stripe.com"
DEFAULT_UPLOAD_BASE = "https://files.stripe.com"
DEFAULT_METER_EVENTS_BASE = "https://meter-events.stripe.com"

@app_info = nil

@config = Stripe::StripeConfiguration.setup
Expand All @@ -76,6 +90,7 @@ class << self
def_delegators :@config, :api_base, :api_base=
def_delegators :@config, :uploads_base, :uploads_base=
def_delegators :@config, :connect_base, :connect_base=
def_delegators :@config, :meter_events_base, :meter_events_base=
def_delegators :@config, :open_timeout, :open_timeout=
def_delegators :@config, :read_timeout, :read_timeout=
def_delegators :@config, :write_timeout, :write_timeout=
Expand Down Expand Up @@ -117,31 +132,6 @@ def self.set_app_info(name, partner_id: nil, url: nil, version: nil)
version: version,
}
end

class RawRequest
include Stripe::APIOperations::Request

def initialize
@opts = {}
end

def execute(method, url, params = {}, opts = {}, usage = [])
resp, = execute_resource_request(method, url, params, opts, usage)

resp
end
end

# Sends a request to Stripe REST API
def self.raw_request(method, url, params = {}, opts = {})
req = RawRequest.new
req.execute(method, url, params, opts, ["raw_request"])
end

def self.deserialize(data)
data = JSON.parse(data) if data.is_a?(String)
Util.convert_to_stripe_object(data, {})
end
end

Stripe.log_level = ENV["STRIPE_LOG"] unless ENV["STRIPE_LOG"].nil?
22 changes: 1 addition & 21 deletions lib/stripe/api_operations/nested_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ def nested_resource_class_methods(resource, path: nil, operations: nil,
end
end

# rubocop:disable Metrics/MethodLength
private def define_operation(
resource,
operation,
Expand All @@ -54,26 +53,8 @@ def nested_resource_class_methods(resource, path: nil, operations: nil,
)
end
when :retrieve
# TODO: (Major) Split params_or_opts to params and opts and get rid of the complicated way to add params
define_singleton_method(:"retrieve_#{resource}") \
do |id, nested_id, params_or_opts = {}, definitely_opts = nil|
opts = nil
params = nil
if definitely_opts.nil?
unrecognized_key = params_or_opts.keys.find { |k| !Util::OPTS_USER_SPECIFIED.include?(k) }
if unrecognized_key
raise ArgumentError,
"Unrecognized request option: #{unrecognized_key}. Did you mean to specify this as " \
"retrieve params? " \
"If so, you must explicitly pass an opts hash as a fourth argument. " \
"For example: .retrieve(#{id}, #{nested_id}, {#{unrecognized_key}: 'foo'}, {})"
end

opts = params_or_opts
else
opts = definitely_opts
params = params_or_opts
end
do |id, nested_id, params = {}, opts = {}|
request_stripe_object(
method: :get,
path: send(resource_url_method, id, nested_id),
Expand Down Expand Up @@ -115,7 +96,6 @@ def nested_resource_class_methods(resource, path: nil, operations: nil,
raise ArgumentError, "Unknown operation: #{operation.inspect}"
end
end
# rubocop:enable Metrics/MethodLength
end
end
end
Loading

0 comments on commit 39d8736

Please sign in to comment.