hoalife 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 898cbe254f04af0df5d1e3edb7d4ef51ccccee6400f7b56ac5b65a1fa0fa16ec
4
+ data.tar.gz: 281fe3403aa5d32b2018f05afc369d29eb8f246a710d896dac786cec58bb2dff
5
+ SHA512:
6
+ metadata.gz: d23041cd85f41453214cbef0e954e1ca1de2d3c6942f91deac1708c281e0654ff981851c4ab306c9928de9f04c4954f0096f69f4e4a84f500544838f786913b2
7
+ data.tar.gz: 455a8251de3cbc64b257ffa28ccc9176adfe330077c0d153794d51dd1410fa22df8a168c5bb039bc2b4f9091095b8c713b47a355c2e4dc4a155e70e55723da8a
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ /dev_test/
10
+ .envrc
@@ -0,0 +1,15 @@
1
+ AllCops:
2
+ Exclude:
3
+ - 'dev_test/**'
4
+ - 'lib/hoalife/concern.rb' # copied from rails source
5
+
6
+ Style/ClassAndModuleChildren:
7
+ EnforcedStyle: compact
8
+
9
+ Metrics/ClassLength:
10
+ Exclude:
11
+ - 'test/**/*_test.rb'
12
+
13
+ Metrics/MethodLength:
14
+ Exclude:
15
+ - 'test/**/*_test.rb'
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.5.1
7
+ before_install: gem install bundler -v 2.0.2
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in hoalife.gemspec
6
+ gemspec
@@ -0,0 +1,62 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ hoalife (0.1.0)
5
+ zeitwerk (~> 2.1)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ addressable (2.6.0)
11
+ public_suffix (>= 2.0.2, < 4.0)
12
+ ast (2.4.0)
13
+ crack (0.4.3)
14
+ safe_yaml (~> 1.0.0)
15
+ ffi (1.11.1)
16
+ hashdiff (1.0.0)
17
+ jaro_winkler (1.5.3)
18
+ listen (3.1.5)
19
+ rb-fsevent (~> 0.9, >= 0.9.4)
20
+ rb-inotify (~> 0.9, >= 0.9.7)
21
+ ruby_dep (~> 1.2)
22
+ minitest (5.11.3)
23
+ parallel (1.17.0)
24
+ parser (2.6.3.0)
25
+ ast (~> 2.4.0)
26
+ public_suffix (3.1.1)
27
+ rainbow (3.0.0)
28
+ rake (10.5.0)
29
+ rb-fsevent (0.10.3)
30
+ rb-inotify (0.10.0)
31
+ ffi (~> 1.0)
32
+ rubocop (0.74.0)
33
+ jaro_winkler (~> 1.5.1)
34
+ parallel (~> 1.10)
35
+ parser (>= 2.6)
36
+ rainbow (>= 2.2.2, < 4.0)
37
+ ruby-progressbar (~> 1.7)
38
+ unicode-display_width (>= 1.4.0, < 1.7)
39
+ ruby-progressbar (1.10.1)
40
+ ruby_dep (1.5.0)
41
+ safe_yaml (1.0.5)
42
+ unicode-display_width (1.6.0)
43
+ webmock (3.6.2)
44
+ addressable (>= 2.3.6)
45
+ crack (>= 0.3.2)
46
+ hashdiff (>= 0.4.0, < 2.0.0)
47
+ zeitwerk (2.1.10)
48
+
49
+ PLATFORMS
50
+ ruby
51
+
52
+ DEPENDENCIES
53
+ bundler (~> 2.0)
54
+ hoalife!
55
+ listen
56
+ minitest (~> 5.0)
57
+ rake (~> 10.0)
58
+ rubocop (~> 0.74)
59
+ webmock
60
+
61
+ BUNDLED WITH
62
+ 2.0.2
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Daniel Westendorf
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,220 @@
1
+ # HOALife - Ruby API Client
2
+
3
+ Pragmatic access to the HOALife REST API. [https://docs.hoalife.com](https://docs.hoalife.com).
4
+
5
+ This library seamlessly handles pagination, CRUD actions, Rate Limiting, and Error handling for you.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'hoalife'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install hoalife
22
+
23
+ ## Usage
24
+
25
+ ### Configuration
26
+
27
+ Configure the client with your credentials in your code.
28
+
29
+ ```ruby
30
+ HOALife.config do |config|
31
+ config.api_key = 'sk_YOURSUPERSECRETKEY'
32
+ config.signing_secret = 'ss_YOURSIGNINGSECRET'
33
+ config.sleep_when_rate_limited = 10.0 # Optional
34
+ end
35
+
36
+ # or
37
+
38
+ HOALife.api_key = 'sk_YOURSUPERSECRETKEY'
39
+ HOALife.signing_secret = 'ss_YOURSIGNINGSECRET'
40
+ HOALife.sleep_when_rate_limited = 10.0 # Optional
41
+ ```
42
+
43
+ Alternatively, you can specify the `api_key`, and `signing_secret` with environmental variables.
44
+
45
+ ```sh
46
+ HOALIFE_API_KEY=sk_YOURSUPERSECRETKEY
47
+ HOALIFE_SIGNING_SECRET=ss_YOURSIGNINGSECRET
48
+
49
+ echo $HOALIFE_API_KEY # => sk_YOURSUPERSECRETKEY
50
+ echo $HOALIFE_SIGNING_SECRET # => ss_YOURSIGNINGSECRET
51
+ ```
52
+
53
+ ### Rate Limits
54
+
55
+ The HOALife API implements per-API Key rate limiting to prevent API abuse from impacting other customers. See the Rate Limiting section of [https://docs.hoalife.com](https://docs.hoalife.com) for details. This library can handle the rate limit in two different ways.
56
+
57
+ #### Sleep When Rate Limited (Default)
58
+
59
+ This method seamlessly handles hitting the rate limit for you by sleeping for a given period then trying the HTTP call when a `429 Rate Limit Exceeded` response is returned by the API. This will make the rate limit transparent to your script, and works best when using the API client in a single threaded, synchronous, fashion.
60
+
61
+ Set `HOALife#sleep_when_rate_limited` to a `Float` to configure the period that the client will sleep for before retrying the HTTP call.
62
+
63
+ #### Raise an Error When Rate Limited
64
+
65
+ If you're accessing the API from multiple machines/threads/processes, you may not want to sleep when the limit is hit, but instead handle the retry logic on your own. In this scenario, a `HOALife::RateLimitError` will be raised.
66
+
67
+ Set `HOALife#sleep_when_rate_limited` to `nil` to configure the client to raise an error instead of sleeping and retrying the HTTP call.
68
+
69
+ ### Error Handling
70
+
71
+ This library tries to handle errors for you in a transparent and intuitive way so that you can resolve them and move forward. See `lib/hoalife/errors.rb` for a full list of the possible errors.
72
+
73
+ #### HTTP Based Errors
74
+
75
+ Errors caused by bad HTTP calls will provide additional information via the `HTTPError#status`, `HTTPError#headers` and `HTTPError#details` methods.
76
+
77
+ ```ruby
78
+ # An invalid API Key
79
+ begin
80
+ HOALife.api_key = 'foo'
81
+ HOALife::Account.create(name: 'foobar')
82
+ rescue HOALife::HTTPError => e
83
+ puts e.status # => 401
84
+ puts e.headers # => {"content-type"=>"application/json; charset=utf-8", ... }
85
+ puts e.details # => {"data"=>{"id"=>"7b06f5e7-a572-4639-bae6-02e41aa367dd", "type"=>"error", "attributes"=>{"id"=>"7b06f5e7-a572-4639-bae6-02e41aa367dd", "title"=>"Invalid API Key", "status"=>401, "detail"=>"Provided API key foo was not valid"}}}
86
+ end
87
+ ```
88
+
89
+ ```ruby
90
+ # API key does not have permission for the given action
91
+ begin
92
+ HOALife::Account.create(name: 'foobar')
93
+ rescue HOALife::HTTPError => e
94
+ puts e.status # => 403
95
+ puts e.headers # => {"x-ratelimit-limit"=>"10", ... }
96
+ puts e.details # => {"data"=>{"id"=>"80143c2b-1b1b-4b33-b31e-751e31da8e5a", "type"=>"error", "attributes"=>{"id"=>"80143c2b-1b1b-4b33-b31e-751e31da8e5a", "title"=>"Permission denied", "status"=>403, "detail"=>"This API key sk_YOURSUPERSECRETKEY does not have access to the requested resource"}}}
97
+ end
98
+ ```
99
+
100
+ ## Implemented Resources
101
+
102
+ Resource | READ | CREATE | UPDATE | DESTROY |
103
+ -------- | ----- |------- | ------ | ------- |
104
+ `HOALife::Account` | true | true | true | true |
105
+ `HOALife::Property` | true | true | true | true |
106
+ `HOALife::CCRArticle` | true | true | true | true |
107
+ `HOALife::CCRViolationType` | true | true | true | true |
108
+ `HOALife::Violation` | true | true | true | true |
109
+ `HOALife::Inspection` | true | false | false | false |
110
+ `HOALife::Escalation` | true | false | false | false |
111
+
112
+ ## Reading Resources
113
+
114
+ Resources respond to many `ActiveRecord`-like methods like `all`, `count`, `first`, `last`, `total_pages`, `reload`, `where`, and `order`. All Resources respond to the Read methods.
115
+
116
+ ### Examples
117
+
118
+ ```ruby
119
+ # Get all accounts
120
+ accounts = HOALife::Account.all
121
+
122
+ # Get the first account
123
+ account = HOALife::Account.first
124
+
125
+ # Total count of the available resources
126
+ count = HOALife::Account.count
127
+
128
+ # Get the most recently created account
129
+ count = HOALife::Account.order(:created_at, :desc).first
130
+
131
+ # Get all accounts that match a condition
132
+ HOALife::Account.where(parent_id: 1).all
133
+
134
+ # Get the first account which matches a condition
135
+ HOALife::Account.where(external_id: 'myInternalId1').first
136
+
137
+ # Get all properties under a given account, ordered by external ID
138
+ HOALife::Property.where(account_id: 3).order(:external_id, :asc).all
139
+ ```
140
+
141
+ ## Creating Resources
142
+
143
+ Resources supporting creation respond to the `HOALife::Resource.create` class method, and the `HOALife::Resource#save` instance method.
144
+
145
+ ### Examples
146
+
147
+ ```ruby
148
+ # Create an account
149
+ account = HOALife::Account.create(parent_id: 1, name: "foo")
150
+ account.id # => 33
151
+ account.errors # => nil
152
+ account.persisted? # => true
153
+
154
+ # or
155
+
156
+ account = HOALife::Account.new(parent_id: 1, name: "foo")
157
+ account.save # => true
158
+ account.errors # => nil
159
+ account.persisted? # => true
160
+
161
+ # Account which doesn't meet data validation requirements
162
+ account = HOALife::Account.create()
163
+ account.id # => nil
164
+ account.persisted? # => false
165
+ account.errors.detail # => {"parent_id"=>"is invalid"}
166
+
167
+ # Property which doesn't meet data validation requirements
168
+ property = HOALife::Property.create(account_id: 2)
169
+ property.errors.detail # => {"street_1"=>"can't be blank", "city"=>"can't be blank", "state"=>"can't be blank", "postal_code"=>"can't be blank"}
170
+ ```
171
+
172
+ ## Updating Resources
173
+
174
+ Resources supporting updating respond to the `HOALife::Resource#save` instance method.
175
+
176
+ ### Examples
177
+
178
+ ```ruby
179
+ # Create an account
180
+ account = HOALife::Account.first
181
+ account.update(name: 'bar') # => true
182
+
183
+ # or
184
+
185
+ account.name = 'bar'
186
+ account.save # => true
187
+ account.name # => 'bar'
188
+
189
+ account.name = ''
190
+ account.save # => false
191
+ account.name # => ''
192
+ account.errors.detail # => {"name"=>"can't be blank"}
193
+ ```
194
+
195
+ ## Destroying Resources
196
+
197
+ Resources supporting deletion respond to the `HOALife::Resource#destroy` instance method.
198
+
199
+ ### Examples
200
+
201
+ ```ruby
202
+ # Create an account
203
+ account = HOALife::Account.first
204
+
205
+ account.destroy # => true
206
+ ```
207
+
208
+ ## Development
209
+
210
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
211
+
212
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
213
+
214
+ ## Contributing
215
+
216
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/hoalife.
217
+
218
+ ## License
219
+
220
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << 'test'
8
+ t.libs << 'lib'
9
+ t.test_files = FileList['test/**/*_test.rb']
10
+ end
11
+
12
+ task default: :test
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'hoalife'
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__)
@@ -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
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'hoalife/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'hoalife'
9
+ spec.version = HOALife::VERSION
10
+ spec.authors = ['Daniel Westendorf']
11
+ spec.email = ['daniel@prowestech.com']
12
+
13
+ spec.summary = 'Ruby API Client for the HOALife.com API'
14
+ spec.description = 'Interface for the HOALife.com HTTP API.'
15
+ spec.homepage = 'https://docs.hoalife.com'
16
+ spec.license = 'MIT'
17
+
18
+ spec.metadata['homepage_uri'] = spec.homepage
19
+ spec.metadata['source_code_uri'] = 'https://github.com/hoalife/hoalife-ruby'
20
+ spec.metadata['changelog_uri'] = 'https://github.com/hoalife/hoalife-ruby/master/CHANGELOG.md'
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
24
+ # have been added into git.
25
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
26
+ `git ls-files -z`.split("\x0").reject do |f|
27
+ f.match(%r{^(test|spec|features)/})
28
+ end
29
+ end
30
+ spec.bindir = 'exe'
31
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
+ spec.require_paths = ['lib']
33
+
34
+ spec.add_dependency 'zeitwerk', '~> 2.1'
35
+
36
+ spec.add_development_dependency 'bundler', '~> 2.0'
37
+ spec.add_development_dependency 'listen', '~> 3.1'
38
+ spec.add_development_dependency 'minitest', '~> 5.0'
39
+ spec.add_development_dependency 'rake', '~> 10.0'
40
+ spec.add_development_dependency 'rubocop', '~> 0.74'
41
+ spec.add_development_dependency 'webmock', '~> 3.6'
42
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Inflector to support the HOAL style of
4
+ # spelling HOALife
5
+ class HOALInflector < Zeitwerk::Inflector
6
+ def camelize(basename, _abspath)
7
+ case basename
8
+ when /(ccr_)(.+)/
9
+ "CCR#{super(Regexp.last_match(2), nil)}"
10
+ when 'hoalife'
11
+ 'HOALife'
12
+ when /Error/
13
+ 'Error'
14
+ else
15
+ super
16
+ end
17
+ end
18
+ end