derek_hall-sdk 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: cf8a7f24372150b936ddc3d3d5cbe9bf4ea0fe28f7f8ec837ad8ef0ca310d92f
4
+ data.tar.gz: ee0ae3a9306cd76a1d8767e4ab1d64479bae94c10ac91c1f81ee0830d80f5a62
5
+ SHA512:
6
+ metadata.gz: 063ad2aeeb3112aeec5b3ee1718c1d275c9289fa833e4be48d95634058675d29a8116bbd14a48900ff6d90078fef297a19fea446eadd723aaa0529b6061e6e43
7
+ data.tar.gz: b7defaf60e45157e1fc9d0e889de44d1492b8f6564ec2f2bc914a97edc29567e4940501931ca60068ccffaa3e0229f3aba9bea00be94208e8a9ef4db35b43caf
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in lotr-sdk.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+ gem "rspec", "~> 3.0"
10
+ gem 'http'
11
+
12
+ group :test do
13
+ gem 'webmock'
14
+ gem 'vcr'
15
+ end
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+
2
+ # LOTR SDK
3
+
4
+ Ruby client for the LOTR api located at https://the-one-api.dev/
5
+
6
+ ## Installation
7
+ gem install derek_hall-SDK
8
+
9
+ ## Usage
10
+ In your ruby file
11
+
12
+ gem 'derek_hall-SDK'
13
+ require 'lotr/sdk'
14
+
15
+ client = Lotr::Sdk::Client.new(ENV['KEY'])
16
+
17
+ # grab a random quote
18
+ random_quote = client.quote_list.data.sample
19
+ puts "Who said #{random_quote['dialog']}?"
20
+
21
+ # get the name and race of the character who was quoted
22
+ character = client.character(id: random_quote['character']).data.first
23
+ puts "Answer: #{character['name']} - #{character['race']}"
24
+
25
+ # gather all pages of quote data
26
+
27
+ full_quote_data = []
28
+ next_page_number = 1
29
+ while next_page_number
30
+ quote_list = client.quote_list(page:next_page_number)
31
+ full_quote_data += quote_list.data
32
+ next_page_number = quote_list.next_page_number
33
+ end
34
+
35
+ puts "Total number of quotes: #{full_quote_data.size}"
36
+
37
+ ## Supported commands
38
+
39
+ * movie_list
40
+ * movie
41
+ * character_list
42
+ * character
43
+ * book_list
44
+ * book
45
+ * quote_list
46
+ * quote
47
+
48
+ ## Local development
49
+ git clone https://github.com/dhall/derek_hall-SDK.git
50
+ cd derek_hall-SDK
51
+ bundle
52
+
53
+ Run tests
54
+
55
+ rake test
56
+
57
+ Build gem
58
+
59
+ rake build
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "lotr/sdk"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/design.md ADDED
@@ -0,0 +1,21 @@
1
+ # LOTR SDK Design Approach
2
+
3
+ ## Constraints
4
+ I needed to time-box this initial version to under 5 hours of effort. Design constraints are a good thing to practice, as in real world problems there are always constraints to consider (time, resources, other requirements, etc).
5
+
6
+ ## Priorities
7
+ Since I knew I would be limited on time, I wanted to get the 'plumbing' in place and prioritize what I worked on. I think it's important to have a testing approach that doesn't rely on the availability of any third party APIs. A few reasons for that are
8
+ * Availability: the status of an API or connectivity to a network should not stop your tests from completing
9
+ * Good stewardship: my development tests will may run very frequently and it's not nice to flood an API with a lot of wasted requests from your test suite
10
+ * Resource management: this API is rate limited, so our tests could cause our real usage to get timed out, but especially in cases where you are paying for a specified amount of requests
11
+
12
+ After the general dev and build overhead was in place, I started building out the usage of SDK. I didn't want a user to need to know a lot about the API or about REST APIs in general. I designed a client that gets instantiated with the secret key. The requests take a natural language approach such as `movie_list` to get a list of movies.
13
+
14
+ I wanted the data returned to be more than raw json data, so it knows something about itself. I called this a `dataset` and the user can easily determine if they have data or an error by methods of those names. When data is present, the dataset also has `meta` information that can be used to gather additional pages of data. As long as `next_page_number` is a truthy value, there is more data available.
15
+
16
+ ## Future Direction
17
+ Even with this simple API, building a robust SDK takes a lot of work. I've only started that process with this first version. Some clear next steps would be
18
+
19
+ * Sorting, ordering, filtering: the API has robust support for these operations so it would be a nice addition to allow doing this on the API side. This would keep from needing to pull all data into the client just to search for a particular entry, for example.
20
+ * Test coverage: The framework and approach is in place, so adding more comprehensive tests would be a good use of time.
21
+ * Full datasets: Adding a method that loops through the operations and gets all data would be useful. It's straightforward to do this on the client side but it would be a nice convenience.
@@ -0,0 +1,56 @@
1
+ require 'http'
2
+ module Lotr
3
+ module Sdk
4
+ class Client
5
+
6
+ def initialize(key)
7
+ @key = key
8
+ @base_url = 'https://the-one-api.dev/v2'
9
+ end
10
+
11
+ def query_api(endpoint,page=nil)
12
+ page_param = "page=#{page}" if page
13
+ HTTP.auth("Bearer #{@key}").get("#{@base_url}/#{endpoint}?#{page_param}")
14
+ end
15
+
16
+ # Movies
17
+ def movie_list(page:1)
18
+ Dataset.new( query_api('movie',page) )
19
+ end
20
+
21
+ def movie(id:)
22
+ Dataset.new( query_api("movie/#{id}") )
23
+ end
24
+
25
+ # Books
26
+ def book_list(page:1)
27
+ Dataset.new( query_api('book',page) )
28
+ end
29
+
30
+ def book(id:)
31
+ Dataset.new( query_api("book/#{id}") )
32
+ end
33
+
34
+ # Quotes
35
+ def quote_list(page:1)
36
+ Dataset.new( query_api('quote',page) )
37
+ end
38
+
39
+ def quote(id:)
40
+ Dataset.new( query_api("quote/#{id}") )
41
+ end
42
+
43
+ # Characters
44
+ def character_list(page:1)
45
+ Dataset.new( query_api('character',page) )
46
+ end
47
+
48
+ def character(id:)
49
+ Dataset.new( query_api("character/#{id}") )
50
+ end
51
+
52
+
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,31 @@
1
+
2
+ module Lotr
3
+ module Sdk
4
+ class Dataset
5
+ attr_accessor :data, :meta, :error
6
+ def initialize(response)
7
+ if response.code < 300
8
+ list = response.parse
9
+ @data = list['docs']
10
+ @meta = {
11
+ total_count: list['total'],
12
+ current_page: list['page'],
13
+ total_pages: list['pages']
14
+ }
15
+ else
16
+ @error = {
17
+ error_code: response.code,
18
+ error_message: response.to_s
19
+ }
20
+ end
21
+ end
22
+
23
+ def next_page_number
24
+ return nil if @error
25
+ @meta[:current_page] < @meta[:total_pages] ? @meta[:current_page] + 1 : nil
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lotr
4
+ module Sdk
5
+ VERSION = "0.3.0"
6
+ end
7
+ end
data/lib/lotr/sdk.rb ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "sdk/version"
4
+ require_relative "sdk/client"
5
+ require_relative "sdk/dataset"
6
+
7
+ module Lotr
8
+ module Sdk
9
+ class Error < StandardError; end
10
+
11
+
12
+ end
13
+ end
data/lotr-sdk.gemspec ADDED
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/lotr/sdk/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "derek_hall-sdk"
7
+ spec.version = Lotr::Sdk::VERSION
8
+ spec.authors = ["Derek Hall"]
9
+ spec.email = ["derekhall77@gmail.com"]
10
+
11
+ spec.summary = "SDK for LOTR api"
12
+ spec.description = "SDK for LOTR api"
13
+ spec.homepage = "https://rubygems.org/gems/derek_hall-sdk"
14
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
15
+
16
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
17
+
18
+ spec.metadata["homepage_uri"] = spec.homepage
19
+ spec.metadata["source_code_uri"] = "https://github.com/dhall"
20
+ spec.metadata["changelog_uri"] = "https://github.com/dhall"
21
+
22
+ # Specify which files should be added to the gem when it is released.
23
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
24
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
25
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
26
+ end
27
+ spec.bindir = "exe"
28
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ["lib"]
30
+
31
+ # Uncomment to register a new dependency of your gem
32
+ spec.add_dependency "http", "~> 5.0"
33
+
34
+ # For more information and examples about making a new gem, checkout our
35
+ # guide at: https://bundler.io/guides/creating_gem.html
36
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: derek_hall-sdk
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Derek Hall
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-08-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: http
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ description: SDK for LOTR api
28
+ email:
29
+ - derekhall77@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".gitignore"
35
+ - ".rspec"
36
+ - Gemfile
37
+ - README.md
38
+ - Rakefile
39
+ - bin/console
40
+ - bin/setup
41
+ - design.md
42
+ - lib/lotr/sdk.rb
43
+ - lib/lotr/sdk/client.rb
44
+ - lib/lotr/sdk/dataset.rb
45
+ - lib/lotr/sdk/version.rb
46
+ - lotr-sdk.gemspec
47
+ homepage: https://rubygems.org/gems/derek_hall-sdk
48
+ licenses: []
49
+ metadata:
50
+ allowed_push_host: https://rubygems.org
51
+ homepage_uri: https://rubygems.org/gems/derek_hall-sdk
52
+ source_code_uri: https://github.com/dhall
53
+ changelog_uri: https://github.com/dhall
54
+ post_install_message:
55
+ rdoc_options: []
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 2.3.0
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ requirements: []
69
+ rubygems_version: 3.2.3
70
+ signing_key:
71
+ specification_version: 4
72
+ summary: SDK for LOTR api
73
+ test_files: []