companies-house-rest 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dbb8d4a36799069defbd9f3780cdacb28d7c063c
4
+ data.tar.gz: 136fef2b3f98e9b5eb31f71e0255b4e68f86f300
5
+ SHA512:
6
+ metadata.gz: f1d9e4f856d027e7125c12b1a9d82a84689c61d1f9f3c07d52635b8d8ac1c78603cfc5c7efa2286a45055ea977a4db3f7943f2a7bb55badda297a2bf629d6810
7
+ data.tar.gz: 307932848e29ebab49d2f88a3c7de393846f102ab12b286dd5bae00d0e2dc6dfd6176b0b3383db9895f6a365399656f0fb8a202afc88333d3a48b0e1055d0bf3
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2016 GOCARDLESS LTD
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,146 @@
1
+ # CompaniesHouse::Client
2
+
3
+ This Gem implements an API client for the Companies House REST API. It can be
4
+ used to look up information about companies registered in the United Kingdom.
5
+ As of July 2016, this API is described by Companies House as a "beta service."
6
+ More information about this free API can be found
7
+ [on the Companies House API website](https://developer.companieshouse.gov.uk/api/docs/index.html).
8
+
9
+ To interact the older [CompaniesHouse XML-based API](http://xmlgw.companieshouse.gov.uk/),
10
+ see the gem [companies-house-gateway](https://github.com/gocardless/companies-house-gateway-ruby).
11
+ (Monthly subscription [fees](http://xmlgw.companieshouse.gov.uk/CHDpriceList.shtml), and other fees, may apply.)
12
+
13
+ Quick start:
14
+ * Register an account via the `Sign In / Register` link
15
+ [on the CompaniesHouse Developers website](https://developer.companieshouse.gov.uk/api/docs/)
16
+ * Register an API key at [Your Applications](https://developer.companieshouse.gov.uk/developer/applications)
17
+ * Put your API key in an environment variable (not in your code):
18
+
19
+ ``` shell
20
+ export COMPANIES_HOUSE_API_KEY=YOUR_API_KEY_HERE
21
+
22
+ ```
23
+ * Install `companies-house-rest` through [RubyGems](https://rubygems.org/gems/companies-house-rest)
24
+ * Create and use a client:
25
+
26
+ ``` ruby
27
+ require 'companies_house/client'
28
+ client = CompaniesHouse::Client.new(api_key: ENV['COMPANIES_HOUSE_API_KEY'])
29
+ profile = client.company('07495895')
30
+ ```
31
+
32
+
33
+ ## Overview
34
+ This gem is meant to provide a simple synchronous API to look up company profile
35
+ information and company officers. The data returned is parsed JSON.
36
+
37
+ This gem provides information on companies by their Companies House company
38
+ number. This "company number" is actually a string and should be treated as such.
39
+ The string may consist solely of digits (including leading 0s) or begin with
40
+ alphabetic characters such as `NI` or `SC`.
41
+
42
+ ## Authentication
43
+
44
+ Using the Companies House REST API requires you to register an account
45
+ [on the CompaniesHouse Developers website](https://developer.companieshouse.gov.uk/api/docs/)
46
+ and [configure an API key](https://developer.companieshouse.gov.uk/developer/applications).
47
+ Developers should read
48
+ [the Companies House developer guidelines](https://developer.companieshouse.gov.uk/api/docs/index/gettingStarted/developerGuidelines.html)
49
+ before using this API, and will note that these guidelines contain several
50
+ instructions regarding API keys:
51
+
52
+ * Do not embed API keys in your code
53
+ * Do not store API keys in your source tree
54
+ * Restrict API key use by IP address and domain
55
+ * **Regenerate your API keys regularly**
56
+ * Delete API keys when no longer required
57
+
58
+ ## Client Initialization
59
+
60
+ All requests to the API are made through a client object:
61
+
62
+ ```ruby
63
+ require 'companies_house/client'
64
+ client = CompaniesHouse::Client.new(config)
65
+ ```
66
+
67
+ The client is configured by passing a hash to the constructor. The supported keys for this
68
+ hash are:
69
+
70
+ | Key | Description |
71
+ | ----------- | ----------- |
72
+ | `:api_key` | Required. The API key received after registration. |
73
+ | `:endpoint` | Optional. Specifies the base URI for the API (e.g. if using a self-hosted version) |
74
+
75
+ ## Requests
76
+
77
+ Once a client has been initialised, requests can be made to the API.
78
+ Details of the available fields in the response are in the Companies House
79
+ [documentation](https://developer.companieshouse.gov.uk/api/docs/index.html).
80
+ The endpoints currently implemented by the gem are:
81
+
82
+ | Client Method | Endpoint | Description |
83
+ | --------------------------- | --------------------------------------- | ----------- |
84
+ | `.company(company_number)` | `GET /company/:company_number` | Retrieves a company profile. |
85
+ | `.officers(company_number)` | `GET /company/:company_number/officers` | Retrieves a list of company officers. |
86
+
87
+ ### .company
88
+ This method implements the [readCompanyProfile](https://developer.companieshouse.gov.uk/api/docs/company/company_number/readCompanyProfile.html)
89
+ API and returns the full [companyProfile](https://developer.companieshouse.gov.uk/api/docs/company/company_number/companyProfile-resource.html)
90
+ resource.
91
+
92
+ ### .officers
93
+ This method implements the [officersList](https://developer.companieshouse.gov.uk/api/docs/company/company_number/officers/officerList.html)
94
+ API. It will make one or more requests against this API, as necessary, to obtain
95
+ the full list of company officers. It returns only the values under the `items`
96
+ key from the
97
+ [officerList](https://developer.companieshouse.gov.uk/api/docs/company/company_number/officers/officerList-resource.html)
98
+ resource(s) which it reads.
99
+
100
+ ### Other API Methods
101
+ While there are other resources exposed by the
102
+ [Companies House API](https://developer.companieshouse.gov.uk/api/docs/index.html),
103
+ this gem does not implement access to these resources at this time.
104
+
105
+ ## Error Handling
106
+ If a request to the Companies House API encounters an HTTP status other than
107
+ `200 OK`, it will raise an instance of `CompaniesHouse::APIError` instead of
108
+ returning response data. The error will have the following fields:
109
+
110
+ | Field | Description |
111
+ | ---------- | ----------- |
112
+ | `response` | The Net::HTTP response object from the failed API call. |
113
+ | `status` | A string containing the response status code. |
114
+
115
+
116
+ Certain API responses will raise an instance of a more specific subclass of
117
+ `CompaniesHouse::APIError`:
118
+
119
+ | Status | Error | Description |
120
+ | ------ | ------------------------------------- | ----------- |
121
+ | 401 | `CompaniesHouse::AuthenticationError` | Authentication error (invalid API key) |
122
+ | 404 | `CompaniesHouse::NotFoundError` | Not Found. (No record of the company is available.) |
123
+ | 429 | `CompaniesHouse::RateLimitError` | Application is being [rate limited](https://developer.companieshouse.gov.uk/api/docs/index/gettingStarted/rateLimiting.html) |
124
+
125
+ The client will not catch any other errors which may occur, such as
126
+ errors involving network connections (e.g. `Errno::ECONNRESET`).
127
+
128
+ ## Development
129
+
130
+ This gem is configured for development using a `bundler` workflow.
131
+ Tests are written using RSpec, and Rubocop is used to provide linting.
132
+ Bug reports and pull requests are welcome on this project's
133
+ [GitHub repository](https://github.com/gocardless/companies-house-ruby).
134
+
135
+ To get started:
136
+
137
+ ``` shell
138
+ bundle install --path vendor
139
+ ```
140
+
141
+
142
+ To run all tests and Rubocop:
143
+
144
+ ```shell
145
+ bundle exec rake
146
+ ```
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'companies_house/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "companies-house-rest"
8
+ spec.version = CompaniesHouse::VERSION
9
+ spec.authors = ["GoCardless Engineering"]
10
+ spec.email = ["developers@gocardless.com"]
11
+ spec.license = "MIT"
12
+
13
+ spec.summary = %q{Look up UK company registration information}
14
+ spec.description = %q{Client for the Companies House REST API. Provides company profiles and officer lists.}
15
+ spec.homepage = "https://github.com/gocardless/companies-house-ruby"
16
+
17
+ spec.files = `git ls-files -z lib/ *.gemspec LICENSE README.md`.split("\x0")
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+ spec.required_ruby_version = '~> 2.0'
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.10"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "rspec", "~> 3.5.0"
26
+ spec.add_development_dependency "rubocop", "~> 0.41.2"
27
+ spec.add_development_dependency "webmock", "~> 2.1.0"
28
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'companies_house/client'
4
+ require 'companies_house/api_error'
5
+ require 'companies_house/not_found_error'
6
+ require 'companies_house/authentication_error'
7
+ require 'companies_house/rate_limit_error'
8
+
9
+ module CompaniesHouse
10
+ # The module that contains all the classes implementing the API client
11
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CompaniesHouse
4
+ # Represents any response from the API which is not a 200 OK
5
+ class APIError < StandardError
6
+ attr_reader :status, :response
7
+
8
+ def initialize(msg, response = nil)
9
+ if response
10
+ msg = "#{msg} - HTTP #{response.code}"
11
+ @status = response.code
12
+ end
13
+
14
+ super(msg)
15
+ @response = response
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CompaniesHouse
4
+ # Specific error class for when an invalid API key is used to access the service
5
+ class AuthenticationError < APIError
6
+ def initialize(response = nil)
7
+ super("Invalid API key", response)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+ require 'companies_house/api_error'
3
+ require 'companies_house/not_found_error'
4
+ require 'companies_house/authentication_error'
5
+ require 'companies_house/rate_limit_error'
6
+ require 'net/http'
7
+ require 'json'
8
+
9
+ module CompaniesHouse
10
+ # This class connects to the Companies House API
11
+ # at https://api.companieshouse.gov.uk
12
+ class Client
13
+ ENDPOINT = 'https://api.companieshouse.gov.uk'
14
+
15
+ attr_reader :api_key, :endpoint
16
+
17
+ def initialize(config)
18
+ raise ArgumentError, 'Missing API key' unless config[:api_key]
19
+ @api_key = config[:api_key]
20
+ @endpoint = URI(config[:endpoint] || ENDPOINT)
21
+ raise ArgumentError, 'HTTP is not supported' if @endpoint.scheme != 'https'
22
+ end
23
+
24
+ def end_connection
25
+ @connection.finish if @connection && @connection.started?
26
+ end
27
+
28
+ def company(id)
29
+ request(id)
30
+ end
31
+
32
+ # The API endpoint for company officers is paginated, and not all of the officers may
33
+ # be returned in the first request. We deal with this by collating all the pages of
34
+ # results into one result set before returning them.
35
+ def officers(id)
36
+ items = []
37
+ offset = 0
38
+
39
+ loop do
40
+ page = request(id, '/officers', start_index: offset)
41
+ total = page['total_results']
42
+ new_items = page['items']
43
+ items += new_items
44
+ offset += new_items.count
45
+
46
+ break if items.count >= total
47
+ end
48
+
49
+ items
50
+ end
51
+
52
+ def connection
53
+ @connection ||= Net::HTTP.new(endpoint.host, endpoint.port).tap do |conn|
54
+ conn.use_ssl = true
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def request(company_id, extra_path = '', params = {})
61
+ uri = URI.join(endpoint, 'company/', "#{company_id}#{extra_path}")
62
+ uri.query = URI.encode_www_form(params)
63
+
64
+ req = Net::HTTP::Get.new(uri)
65
+ req.basic_auth api_key, ''
66
+
67
+ response = connection.request req
68
+ parse(response, company_id)
69
+ end
70
+
71
+ def parse(response, company_id)
72
+ case response.code
73
+ when '200'
74
+ return JSON[response.body]
75
+ when '401'
76
+ raise CompaniesHouse::AuthenticationError, response
77
+ when '404'
78
+ raise CompaniesHouse::NotFoundError.new(company_id, response)
79
+ when '429'
80
+ raise CompaniesHouse::RateLimitError, response
81
+ else
82
+ raise CompaniesHouse::APIError.new("Unknown API response", response)
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CompaniesHouse
4
+ # Specific error class for when a company cannot be found (for example, if the company
5
+ # number given is invaid)
6
+ class NotFoundError < APIError
7
+ def initialize(company_id = nil, response = nil)
8
+ super("Company #{company_id || 'nil'} not found", response)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CompaniesHouse
4
+ # Specific error class for when an invalid API key is used to access the service
5
+ class RateLimitError < APIError
6
+ def initialize(response = nil)
7
+ super("Rate limit exceeded", response)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CompaniesHouse
4
+ VERSION = '0.1.2'
5
+ end
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: companies-house-rest
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - GoCardless Engineering
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-07-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 3.5.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 3.5.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.41.2
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 0.41.2
69
+ - !ruby/object:Gem::Dependency
70
+ name: webmock
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: 2.1.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: 2.1.0
83
+ description: Client for the Companies House REST API. Provides company profiles and
84
+ officer lists.
85
+ email:
86
+ - developers@gocardless.com
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - LICENSE
92
+ - README.md
93
+ - companies-house-rest.gemspec
94
+ - lib/companies-house.rb
95
+ - lib/companies_house/api_error.rb
96
+ - lib/companies_house/authentication_error.rb
97
+ - lib/companies_house/client.rb
98
+ - lib/companies_house/not_found_error.rb
99
+ - lib/companies_house/rate_limit_error.rb
100
+ - lib/companies_house/version.rb
101
+ homepage: https://github.com/gocardless/companies-house-ruby
102
+ licenses:
103
+ - MIT
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ~>
112
+ - !ruby/object:Gem::Version
113
+ version: '2.0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubyforge_project:
121
+ rubygems_version: 2.0.14.1
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: Look up UK company registration information
125
+ test_files: []