diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d9d8e32..6cb38b47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ Note: For changes to the API, see https://shopify.dev/changelog?filter=api ## Unreleased +- [#1375](https://github.com/Shopify/shopify-api-ruby/pull/1375) add optional ShopifyAPI::Context::httparty_params ## 14.9.0 diff --git a/README.md b/README.md index 8449a265..d8037020 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,24 @@ ShopifyAPI::Context.setup( ) ``` +Optionally, you can override HTTP request params such as timeout, debug_output, or proxy settings. +```ruby +ShopifyAPI::Context.setup( + # other params... + httparty_params: { + timeout: 60, # Set the open/read/write timeout for HTTP requests + open_timeout: 60, # Set the open timeout for HTTP requests + read_timeout: 60, # Set the read timeout for HTTP requests + write_timeout: 60, # Set the write timeout for HTTP requests + debug_output: false, # Set to true to enable debug output for HTTP requests + http_proxyaddr: "http://proxy.example.com:8080", # Set the HTTP proxy address + http_proxyport: 8080, # Set the HTTP proxy port + http_proxyuser: "username", # Set the HTTP proxy username + http_proxypass: "password", # Set the HTTP proxy password + } +) +``` + ### Performing OAuth You need to go through OAuth as described [here](https://shopify.dev/docs/apps/auth/oauth) to create sessions for shops using your app. diff --git a/lib/shopify_api/clients/http_client.rb b/lib/shopify_api/clients/http_client.rb index fbdc3999..1ea94ff9 100644 --- a/lib/shopify_api/clients/http_client.rb +++ b/lib/shopify_api/clients/http_client.rb @@ -51,6 +51,7 @@ def request(request, response_as_struct: false) res = T.cast(HTTParty.send( request.http_method, parsed_uri.to_s, + **Context.httparty_params, headers: headers, query: request.query, body: request.body.class == Hash ? T.unsafe(request.body).to_json : request.body, diff --git a/lib/shopify_api/context.rb b/lib/shopify_api/context.rb index 06349d65..24322622 100644 --- a/lib/shopify_api/context.rb +++ b/lib/shopify_api/context.rb @@ -26,6 +26,8 @@ class Context @rest_resource_loader = T.let(nil, T.nilable(Zeitwerk::Loader)) + @httparty_params = T.let({}, T::Hash[Symbol, T.untyped]) + class << self extend T::Sig @@ -47,6 +49,7 @@ class << self api_host: T.nilable(String), response_as_struct: T.nilable(T::Boolean), rest_disabled: T.nilable(T::Boolean), + httparty_params: T::Hash[Symbol, T.untyped] ).void end def setup( @@ -65,7 +68,8 @@ def setup( old_api_secret_key: nil, api_host: nil, response_as_struct: false, - rest_disabled: false + rest_disabled: false, + httparty_params: {} ) unless ShopifyAPI::AdminVersions::SUPPORTED_ADMIN_VERSIONS.include?(api_version) raise Errors::UnsupportedVersionError, @@ -93,6 +97,7 @@ def setup( end load_rest_resources(api_version: api_version) + @httparty_params = httparty_params end sig { params(api_version: String).void } @@ -148,6 +153,9 @@ def private? sig { returns(T.nilable(String)) } attr_reader :private_shop, :user_agent_prefix, :old_api_secret_key, :host, :api_host + sig { returns(T::Hash[Symbol, T.untyped]) } + attr_reader :httparty_params + sig { returns(T::Boolean) } def embedded? @is_embedded diff --git a/test/context_test.rb b/test/context_test.rb index a508a56c..581f918f 100644 --- a/test/context_test.rb +++ b/test/context_test.rb @@ -46,6 +46,7 @@ def test_setup assert_equal("http", ShopifyAPI::Context.host_scheme) assert_equal("localhost", ShopifyAPI::Context.host_name) assert_equal("example.com", ShopifyAPI::Context.api_host) + assert_equal({}, ShopifyAPI::Context.httparty_params) ShopifyAPI::Context.setup( api_key: "key", @@ -146,6 +147,49 @@ def test_with_host_name_and_no_host_env ENV["HOST"] = old_host end + def test_with_httparty_params + clear_context + + ShopifyAPI::Context.setup( + api_key: "key", + api_secret_key: "secret", + api_version: "2023-10", + scope: ["scope1", "scope2"], + is_private: true, + is_embedded: true, + log_level: :off, + private_shop: "privateshop.myshopify.com", + user_agent_prefix: "user_agent_prefix1", + old_api_secret_key: "old_secret", + api_host: "example.com", + httparty_params: { + timeout: 10, + open_timeout: 20, + read_timeout: 30, + write_timeout: 40, + debug_output: true, + http_proxyaddr: "my.proxy.server", + http_proxyport: 8000, + http_proxyuser: "user", + http_proxypass: "pass", + }, + ) + assert_equal( + { + timeout: 10, + open_timeout: 20, + read_timeout: 30, + write_timeout: 40, + debug_output: true, + http_proxyaddr: "my.proxy.server", + http_proxyport: 8000, + http_proxyuser: "user", + http_proxypass: "pass", + }, + ShopifyAPI::Context.httparty_params, + ) + end + def test_send_a_warning_if_log_level_is_invalid ShopifyAPI::Context.stubs(:log_level).returns(:warn) ShopifyAPI::Logger.expects(:warn).with("not_a_level is not a valid log_level. "\