Class: Gems::Client

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
API, ClientCredentials
Defined in:
lib/gems/client.rb

Overview

A client for the RubyGems API

Instance Attribute Summary collapse

Attributes included from ClientCredentials

#id_token, #key, #otp, #password, #username

Class Method Summary collapse

Instance Method Summary collapse

Methods included from API::WebHookEndpoints

#add_web_hook, #fire_web_hook, #remove_web_hook, #web_hooks

Methods included from API::VersionEndpoints

#attestations, #contents, #latest_version, #timeframe_versions, #timeframe_versions_each, #version, #versions

Methods included from API::TrustedPublisherEndpoints

#add_trusted_publisher, #remove_trusted_publisher, #trusted_publisher, #trusted_publishers

Methods included from API::ProfileEndpoints

#me, #profile, #webauthn_verification, #webauthn_verification_status

Methods included from API::OwnerEndpoints

#add_owner, #owners, #remove_owner, #update_owner

Methods included from API::GemEndpoints

#autocomplete, #owned_gems, #push, #reverse_dependencies, #reverse_dependency_versions, #rubygem, #search, #search_each, #yank

Methods included from API::DownloadEndpoints

#downloads, #most_downloaded, #total_downloads

Methods included from API::APIKeyEndpoints

#api_key_role, #api_key_roles, #assume_api_key_role, #create_api_key, #exchange_trusted_publisher_token, #oidc_id_token, #oidc_id_tokens, #oidc_provider, #oidc_providers, #update_api_key

Methods included from API::ActivityEndpoints

#just_updated, #latest

Constructor Details

#initialize(host: Gems.host, key: UNSET, username: Gems.username, password: Gems.password, otp: Gems.otp, id_token: Gems.id_token, user_agent: Gems.user_agent, open_timeout: Gems.open_timeout, read_timeout: Gems.read_timeout, write_timeout: Gems.write_timeout, debug_output: Gems.debug_output, proxy_url: Gems.proxy_url, keep_alive_timeout: Gems.keep_alive_timeout, max_redirects: Gems.max_redirects, max_retries: Gems.max_retries, max_retry_delay: Gems.max_retry_delay, ca_file: Gems.ca_file, ca_path: Gems.ca_path, cert_store: Gems.cert_store, client_cert: Gems.client_cert, client_key: Gems.client_key) ⇒ Client

Initialize a new RubyGems API client

Every option defaults to the global configuration (see Gems.configure).

Examples:

Create a client with an API key

client = Gems::Client.new(key: "rubygems_701243f217cdf23b1370c7b66b65ca97")

Create a client with HTTP basic authentication

client = Gems::Client.new(username: "[email protected]", password: "schwwwwing")

Create a client with an API key and a one-time passcode

client = Gems::Client.new(key: "rubygems_701243f217cdf23b1370c7b66b65ca97", otp: "123456")

Create a client for trusted publishing

client = Gems::Client.new(id_token: ENV.fetch("ID_TOKEN"))

Create a client for a host with a certificate of its own

client = Gems::Client.new(host: "https://gems.example.com", ca_file: "/etc/ssl/certs/internal.pem")

Parameters:

  • host (String) (defaults to: Gems.host) —

    the host for API requests, including scheme

  • key (String, APIKey, nil) (defaults to: UNSET) —

    the API key, an API key object, or nil to send requests without one

  • username (String, nil) (defaults to: Gems.username) —

    the username for HTTP basic authentication

  • password (String, nil) (defaults to: Gems.password) —

    the password for HTTP basic authentication

  • otp (String, nil) (defaults to: Gems.otp) —

    the one-time passcode for multi-factor authentication

  • id_token (String, nil) (defaults to: Gems.id_token) —

    the OIDC ID token for trusted publishing

  • user_agent (String) (defaults to: Gems.user_agent) —

    the 'User-Agent' HTTP header sent with requests

  • open_timeout (Numeric) (defaults to: Gems.open_timeout) —

    the timeout for opening connections in seconds

  • read_timeout (Numeric) (defaults to: Gems.read_timeout) —

    the timeout for reading responses in seconds

  • write_timeout (Numeric) (defaults to: Gems.write_timeout) —

    the timeout for writing requests in seconds

  • debug_output (IO, nil) (defaults to: Gems.debug_output) —

    the IO object for debug output

  • proxy_url (String, nil) (defaults to: Gems.proxy_url) —

    the proxy URL for requests

  • keep_alive_timeout (Numeric) (defaults to: Gems.keep_alive_timeout) —

    the seconds an idle connection is kept open for another request

  • max_redirects (Integer) (defaults to: Gems.max_redirects) —

    the maximum number of redirects to follow

  • max_retries (Integer) (defaults to: Gems.max_retries) —

    the number of times a request that was turned away is sent again

  • max_retry_delay (Numeric) (defaults to: Gems.max_retry_delay) —

    the longest a request waits before it is sent again, in seconds

  • ca_file (String, nil) (defaults to: Gems.ca_file) —

    the path of a file of certificates TLS is verified with

  • ca_path (String, nil) (defaults to: Gems.ca_path) —

    the path of a directory of certificates TLS is verified with

  • cert_store (OpenSSL::X509::Store, nil) (defaults to: Gems.cert_store) —

    the store of certificates TLS is verified with

  • client_cert (OpenSSL::X509::Certificate, nil) (defaults to: Gems.client_cert) —

    the certificate presented to a host that asks for one

  • client_key (OpenSSL::PKey::PKey, nil) (defaults to: Gems.client_key) —

    the private key of the client certificate

Raises:

  • (ArgumentError) —

    if the host is not an HTTP or HTTPS URL, or a certificate path names nothing



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/gems/client.rb', line 115

def initialize(host: Gems.host, key: UNSET, username: Gems.username, password: Gems.password,
  otp: Gems.otp, id_token: Gems.id_token,
  user_agent: Gems.user_agent,
  open_timeout: Gems.open_timeout,
  read_timeout: Gems.read_timeout,
  write_timeout: Gems.write_timeout,
  debug_output: Gems.debug_output,
  proxy_url: Gems.proxy_url,
  keep_alive_timeout: Gems.keep_alive_timeout,
  max_redirects: Gems.max_redirects,
  max_retries: Gems.max_retries,
  max_retry_delay: Gems.max_retry_delay,
  ca_file: Gems.ca_file, ca_path: Gems.ca_path, cert_store: Gems.cert_store,
  client_cert: Gems.client_cert, client_key: Gems.client_key)
  @host = validate_host(host)
  @connection = Connection.new(open_timeout:, read_timeout:, write_timeout:, debug_output:, proxy_url:,
    keep_alive_timeout:, ca_file:, ca_path:, cert_store:, client_cert:, client_key:)
  @request_builder = RequestBuilder.new(user_agent:)
  @redirect_handler = RedirectHandler.new(connection: @connection, request_builder: @request_builder, max_redirects:)
  @retry_handler = RetryHandler.new(max_retries:, max_retry_delay:)
  initialize_credentials(key:, username:, password:, otp:, id_token:)
  initialize_authenticator
  @response_parser = ResponseParser.new
end

Instance Attribute Details

#host ⇒ String

The host for API requests

Examples:

Get the host

client.host

Returns:

  • (String) —

    the host for API requests, including scheme



32
33
34
# File 'lib/gems/client.rb', line 32

def host
  @host
end

Class Method Details

.new(**options) {|client| ... } ⇒ Client, Object

Build a client, and close it once a block is done with it

Without a block the client is returned, as it is from any other constructor. With one, the client is given to the block and its connections are closed once the block returns or raises, as Net::HTTP.start closes the connection it opened, and what the block returns is returned. The client can still be used afterwards, since a closed client opens its connections again as it needs them.

The options are handed to #initialize, which is what declares them, so they are collected here and named there.

Examples:

Close the connections of a client once a series of requests is done

versions = Gems::Client.new(key: "rubygems_701243f217cdf23b1370c7b66b65ca97") do |client|
  client.versions("rails")
end

Parameters:

Yields:

  • (client) —

    the client, which is closed once the block is done with it

Returns:

  • (Client, Object) —

    the client, or what the block returned



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/gems/client.rb', line 65

def self.new(**options) # steep:ignore DifferentMethodParameterKind
  client = super

  return client unless block_given?

  begin
    yield client
  ensure
    client.close
  end
end

Instance Method Details

#close ⇒ Client

Close the connections the client keeps open for the next request

The connections are opened again as they are needed, so requests can still be made afterwards.

Examples:

Close the connections a client keeps open

client.close

Returns:



177
178
179
180
# File 'lib/gems/client.rb', line 177

def close
  @connection.close
  self
end

#delete(path, params = {}, headers: {}, host: nil) ⇒ String

Perform a DELETE request to the RubyGems API

Examples:

Remove an owner from a gem

client.delete("/api/v1/gems/gems/owners", {email: "[email protected]"})

Parameters:

  • path (String) —

    the request path

  • params (Hash) (defaults to: {}) —

    the query parameters

  • headers (Hash{String => String}) (defaults to: {}) —

    the headers to send with the request, besides the 'User-Agent' and the credentials of the client

  • host (String, nil) (defaults to: nil) —

    the host for the request (defaults to the client's host)

Returns:

  • (String) —

    the response body

Raises:

  • (HTTPError) —

    if the response is not successful

  • (ArgumentError) —

    if the path is a URL of an origin other than the host



214
215
216
# File 'lib/gems/client.rb', line 214

def delete(path, params = {}, headers: {}, host: nil)
  execute_request(:delete, path, params:, headers:, host:)
end

#get(path, params = {}, headers: {}, host: nil) ⇒ String

Perform a GET request to the RubyGems API

Examples:

Get information about a gem

client.get("/api/v1/gems/rails.json")

Send a header of your own

client.get("/api/v1/gems/rails.json", headers: {"Accept" => "application/json"})

Parameters:

  • path (String) —

    the request path

  • params (Hash) (defaults to: {}) —

    the query parameters

  • headers (Hash{String => String}) (defaults to: {}) —

    the headers to send with the request, besides the 'User-Agent' and the credentials of the client

  • host (String, nil) (defaults to: nil) —

    the host for the request (defaults to the client's host)

Returns:

  • (String) —

    the response body

Raises:

  • (HTTPError) —

    if the response is not successful

  • (ArgumentError) —

    if the path is a URL of an origin other than the host



197
198
199
# File 'lib/gems/client.rb', line 197

def get(path, params = {}, headers: {}, host: nil)
  execute_request(:get, path, params:, headers:, host:)
end

#inspect ⇒ String

Summarize the client for the console

Examples:

Inspect a client

client.inspect # => #<Gems::Client host="https://rubygems.org" authenticator=#<Gems::APIKeyAuthenticator>>

Returns:

  • (String) —

    the summary, which includes the host and authenticator but never credentials



165
166
167
# File 'lib/gems/client.rb', line 165

def inspect
  "#<#{self.class} host=#{host.inspect} authenticator=#{authenticator.inspect}>"
end

#patch(path, body = {}, content_type: nil, headers: {}, host: nil) ⇒ String

Perform a PATCH request to the RubyGems API

Examples:

Update the scopes of an API key

client.patch("/api/v1/api_key", {api_key: "rubygems_701243f217cdf23b1370c7b66b65ca97", yank_rubygem: true})

Parameters:

  • path (String) —

    the request path

  • body (Hash, Array, String) (defaults to: {}) —

    the request body (form fields, multipart fields, or raw data)

  • content_type (String, nil) (defaults to: nil) —

    the content type for a String body (defaults to application/octet-stream)

  • headers (Hash{String => String}) (defaults to: {}) —

    the headers to send with the request, besides the 'User-Agent', the content type, and the credentials of the client

  • host (String, nil) (defaults to: nil) —

    the host for the request (defaults to the client's host)

Returns:

  • (String) —

    the response body

Raises:

  • (HTTPError) —

    if the response is not successful

  • (ArgumentError) —

    if the path is a URL of an origin other than the host



268
269
270
# File 'lib/gems/client.rb', line 268

def patch(path, body = {}, content_type: nil, headers: {}, host: nil)
  execute_request(:patch, path, body:, content_type:, headers:, host:)
end

#post(path, body = {}, content_type: nil, headers: {}, host: nil) ⇒ String

Perform a POST request to the RubyGems API

Examples:

Add an owner to a gem

client.post("/api/v1/gems/gems/owners", {email: "[email protected]"})

Parameters:

  • path (String) —

    the request path

  • body (Hash, Array, String) (defaults to: {}) —

    the request body (form fields, multipart fields, or raw data)

  • content_type (String, nil) (defaults to: nil) —

    the content type for a String body (defaults to application/octet-stream)

  • headers (Hash{String => String}) (defaults to: {}) —

    the headers to send with the request, besides the 'User-Agent', the content type, and the credentials of the client

  • host (String, nil) (defaults to: nil) —

    the host for the request (defaults to the client's host)

Returns:

  • (String) —

    the response body

Raises:

  • (HTTPError) —

    if the response is not successful

  • (ArgumentError) —

    if the path is a URL of an origin other than the host



232
233
234
# File 'lib/gems/client.rb', line 232

def post(path, body = {}, content_type: nil, headers: {}, host: nil)
  execute_request(:post, path, body:, content_type:, headers:, host:)
end

#put(path, body = {}, content_type: nil, headers: {}, host: nil) ⇒ String

Perform a PUT request to the RubyGems API

Examples:

Update the role of an owner

client.put("/api/v1/gems/gems/owners", {email: "[email protected]", role: "maintainer"})

Parameters:

  • path (String) —

    the request path

  • body (Hash, Array, String) (defaults to: {}) —

    the request body (form fields, multipart fields, or raw data)

  • content_type (String, nil) (defaults to: nil) —

    the content type for a String body (defaults to application/octet-stream)

  • headers (Hash{String => String}) (defaults to: {}) —

    the headers to send with the request, besides the 'User-Agent', the content type, and the credentials of the client

  • host (String, nil) (defaults to: nil) —

    the host for the request (defaults to the client's host)

Returns:

  • (String) —

    the response body

Raises:

  • (HTTPError) —

    if the response is not successful

  • (ArgumentError) —

    if the path is a URL of an origin other than the host



250
251
252
# File 'lib/gems/client.rb', line 250

def put(path, body = {}, content_type: nil, headers: {}, host: nil)
  execute_request(:put, path, body:, content_type:, headers:, host:)
end