Module: Heroics

Extended by:
Heroics
Included in:
Heroics
Defined in:
lib/heroics.rb,
lib/heroics/cli.rb,
lib/heroics/link.rb,
lib/heroics/client.rb,
lib/heroics/errors.rb,
lib/heroics/naming.rb,
lib/heroics/schema.rb,
lib/heroics/command.rb,
lib/heroics/version.rb,
lib/heroics/resource.rb,
lib/heroics/configuration.rb,
lib/heroics/client_generator.rb

Overview

Heroics is an HTTP client for an API described by a JSON schema.

Defined Under Namespace

Modules: NullRateLimit Classes: BodyParameter, CLI, Client, Command, Configuration, GeneratorLink, GeneratorResource, Link, LinkSchema, Parameter, ParameterChoice, Resource, ResourceSchema, Schema, SchemaError

Constant Summary collapse

VERSION =
'0.1.2'

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.cli_from_schema(name, output, schema, url, options = {}) ⇒ CLI

Create a CLI from a JSON schema.

Parameters:

  • name (String)

    The name of the CLI.

  • output (IO)

    The stream to write to.

  • schema (Hash)

    The JSON schema to use with the CLI.

  • url (String)

    The URL used by the generated CLI when it makes requests.

  • options (Hash) (defaults to: {})

    Configuration for links. Possible keys include:

    • default_headers: Optionally, a set of headers to include in every request made by the CLI. Default is no custom headers.

    • cache: Optionally, a Moneta-compatible cache to store ETags. Default is no caching.

Returns:

  • (CLI)

    A CLI with commands generated from the JSON schema.



78
79
80
81
82
83
84
85
86
87
88
# File 'lib/heroics/cli.rb', line 78

def self.cli_from_schema(name, output, schema, url, options={})
  client = client_from_schema(schema, url, options)
  commands = {}
  schema.resources.each do |resource_schema|
    resource_schema.links.each do |link_schema|
      command = Command.new(name, link_schema, client, output)
      commands[command.name] = command
    end
  end
  CLI.new(name, commands, output)
end

.client_from_schema(schema, url, options = {}) ⇒ Client

Create an HTTP client from a JSON schema.

Parameters:

  • schema (Schema)

    The JSON schema to build an HTTP client for.

  • url (String)

    The URL the generated client should use when making requests. Include the username and password to use with HTTP basic auth.

  • options (Hash) (defaults to: {})

    Configuration for links. Possible keys include:

    • default_headers: Optionally, a set of headers to include in every request made by the client. Default is no custom headers.

    • cache: Optionally, a Moneta-compatible cache to store ETags. Default is no caching.

Returns:

  • (Client)

    A client with resources and links from the JSON schema.



59
60
61
62
63
64
65
66
67
68
69
# File 'lib/heroics/client.rb', line 59

def self.client_from_schema(schema, url, options={})
  resources = {}
  schema.resources.each do |resource_schema|
    links = {}
    resource_schema.links.each do |link_schema|
      links[link_schema.name] = Link.new(url, link_schema, options)
    end
    resources[resource_schema.name] = Resource.new(links)
  end
  Client.new(resources, url)
end

.download_schema(url, options = {}) ⇒ Schema

Download a JSON schema from a URL.

Parameters:

  • url (String)

    The URL for the schema.

  • options (Hash) (defaults to: {})

    Configuration for links. Possible keys include:

    • default_headers: Optionally, a set of headers to include in every request made by the client. Default is no custom headers.

Returns:

  • (Schema)

    The downloaded JSON schema.



356
357
358
359
360
# File 'lib/heroics/schema.rb', line 356

def self.download_schema(url, options={})
  default_headers = options.fetch(:default_headers, {})
  response = Excon.get(url, headers: default_headers, expects: [200, 201])
  Schema.new(MultiJson.load(response.body))
end

.generate_clientObject

Generate a static client that uses Heroics under the hood. This is a good option if you want to ship a gem or generate API documentation using Yard.



5
6
7
8
9
10
11
12
13
# File 'lib/heroics/client_generator.rb', line 5

def self.generate_client
  filename = File.dirname(__FILE__) + '/views/client.erb'
  eruby = Erubis::Eruby.new(File.read(filename))
  context = build_context(Heroics::Configuration.defaults.module_name,
    Heroics::Configuration.defaults.schema,
    Heroics::Configuration.defaults.base_url,
    Heroics::Configuration.defaults.options)
  eruby.evaluate(context)
end

.oauth_client_from_schema(oauth_token, schema, url, options = {}) ⇒ Client

Create an HTTP client with OAuth credentials from a JSON schema.

Parameters:

  • oauth_token (String)

    The OAuth token to pass using the ‘Bearer` authorization mechanism.

  • schema (Schema)

    The JSON schema to build an HTTP client for.

  • url (String)

    The URL the generated client should use when making requests.

  • options (Hash) (defaults to: {})

    Configuration for links. Possible keys include:

    • default_headers: Optionally, a set of headers to include in every request made by the client. Default is no custom headers.

    • cache: Optionally, a Moneta-compatible cache to store ETags. Default is no caching.

Returns:

  • (Client)

    A client with resources and links from the JSON schema.



84
85
86
87
88
89
90
91
92
93
# File 'lib/heroics/client.rb', line 84

def self.oauth_client_from_schema(oauth_token, schema, url, options={})
  authorization = "Bearer #{oauth_token}"
  # Don't mutate user-supplied data.
  options = Marshal.load(Marshal.dump(options))
  if !options.has_key?(:default_headers)
    options[:default_headers] = {}
  end
  options[:default_headers].merge!({"Authorization" => authorization})
  client_from_schema(schema, url, options)
end

.pretty_name(name) ⇒ String

Process a name to make it suitable for use as a pretty command name.

Parameters:

  • name (String)

    The name to process.

Returns:

  • (String)

    The new name with capitals converted to lowercase, and underscores and spaces converted to dashes.



26
27
28
# File 'lib/heroics/naming.rb', line 26

def self.pretty_name(name)
  name.downcase.gsub(/[_ ]/, '-')
end

.ruby_name(name) ⇒ String

Process a name to make it suitable for use as a Ruby method name.

Parameters:

  • name (String)

    The name to process.

Returns:

  • (String)

    The new name with capitals converted to lowercase, and characters replaced or removed based on the Configuration.ruby_names_replacement_patterns rules

Raises:

  • (SchemaError)

    Raised if the name contains invalid characters.



10
11
12
13
14
15
16
17
18
19
# File 'lib/heroics/naming.rb', line 10

def self.ruby_name(name)
  patterns = Heroics::Configuration.defaults.ruby_name_replacement_patterns

  ruby_name = patterns.reduce(name.downcase) do |memo, (regex, replacement)|
    memo.gsub(regex, replacement)
  end

  raise SchemaError.new("Name '#{name}' converts to invalid Ruby name '#{ruby_name}'.") if ruby_name =~ /\W/
  ruby_name
end

.token_client_from_schema(token, schema, url, options = {}) ⇒ Client

Create an HTTP client with Token credentials from a JSON schema.

Parameters:

  • oauth_token (String)

    The token to pass using the ‘Bearer` authorization mechanism.

  • schema (Schema)

    The JSON schema to build an HTTP client for.

  • url (String)

    The URL the generated client should use when making requests.

  • options (Hash) (defaults to: {})

    Configuration for links. Possible keys include:

    • default_headers: Optionally, a set of headers to include in every request made by the client. Default is no custom headers.

    • cache: Optionally, a Moneta-compatible cache to store ETags. Default is no caching.

Returns:

  • (Client)

    A client with resources and links from the JSON schema.



108
109
110
111
112
113
114
115
116
117
# File 'lib/heroics/client.rb', line 108

def self.token_client_from_schema(token, schema, url, options={})
  authorization = "Token token=#{token}"
  # Don't mutate user-supplied data.
  options = Marshal.load(Marshal.dump(options))
  if !options.has_key?(:default_headers)
    options[:default_headers] = {}
  end
  options[:default_headers].merge!({"Authorization" => authorization})
  client_from_schema(schema, url, options)
end

Instance Method Details

#default_configuration(&block) ⇒ Object



14
15
16
17
# File 'lib/heroics.rb', line 14

def default_configuration(&block)
  block ||= lambda { |c| }
  Heroics::Configuration.defaults.tap(&block)
end