quandl_client 2.7.5 → 2.7.6
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.
- data/.gitignore +7 -7
- data/.rspec +1 -1
- data/.travis.yml +20 -20
- data/.yardopts +2 -2
- data/Gemfile +12 -12
- data/Guardfile +8 -8
- data/LICENSE +7 -7
- data/README.md +303 -303
- data/Rakefile +31 -35
- data/UPGRADE.md +190 -213
- data/VERSION +1 -1
- data/examples/create.rb +32 -32
- data/examples/find.rb +17 -17
- data/examples/login.rb +12 -12
- data/examples/search.rb +12 -12
- data/examples/trims.rb +15 -15
- data/lib/quandl/client.rb +49 -49
- data/lib/quandl/client/base.rb +91 -91
- data/lib/quandl/client/base/attributes.rb +15 -15
- data/lib/quandl/client/base/model.rb +40 -40
- data/lib/quandl/client/base/search.rb +74 -74
- data/lib/quandl/client/base/validation.rb +101 -101
- data/lib/quandl/client/middleware.rb +9 -9
- data/lib/quandl/client/middleware/parse_json.rb +85 -85
- data/lib/quandl/client/models/dataset.rb +261 -245
- data/lib/quandl/client/models/dataset/data.rb +57 -57
- data/lib/quandl/client/models/location.rb +10 -10
- data/lib/quandl/client/models/report.rb +14 -14
- data/lib/quandl/client/models/scraper.rb +16 -16
- data/lib/quandl/client/models/sheet.rb +50 -50
- data/lib/quandl/client/models/source.rb +48 -40
- data/lib/quandl/client/models/superset.rb +59 -59
- data/lib/quandl/client/models/user.rb +7 -7
- data/lib/quandl/client/version.rb +14 -14
- data/lib/quandl/her/remove_method_data.rb +8 -8
- data/lib/quandl/pattern.rb +37 -37
- data/lib/quandl/pattern/client.rb +8 -8
- data/quandl_client.gemspec +33 -33
- data/spec/factories/dataset.rb +10 -10
- data/spec/factories/sheet.rb +7 -7
- data/spec/factories/source.rb +9 -9
- data/spec/fixtures/scraper.rb +5 -5
- data/spec/lib/quandl/client/dataset/attributes_spec.rb +63 -63
- data/spec/lib/quandl/client/dataset/data_spec.rb +92 -92
- data/spec/lib/quandl/client/dataset/location_spec.rb +65 -65
- data/spec/lib/quandl/client/dataset/persistence_spec.rb +104 -104
- data/spec/lib/quandl/client/dataset/search_spec.rb +19 -19
- data/spec/lib/quandl/client/dataset/source_spec.rb +47 -47
- data/spec/lib/quandl/client/dataset/trim_spec.rb +35 -35
- data/spec/lib/quandl/client/dataset/validation_spec.rb +68 -68
- data/spec/lib/quandl/client/dataset_spec.rb +57 -57
- data/spec/lib/quandl/client/scraper_spec.rb +71 -71
- data/spec/lib/quandl/client/sheet_spec.rb +37 -37
- data/spec/lib/quandl/client/source_spec.rb +51 -51
- data/spec/spec_helper.rb +30 -30
- metadata +27 -5
@@ -1,58 +1,58 @@
|
|
1
|
-
class Quandl::Client::Dataset::Data < Quandl::Client::Base
|
2
|
-
|
3
|
-
@_her_resource_path = "datasets/:id/data"
|
4
|
-
|
5
|
-
has_scope_composer
|
6
|
-
|
7
|
-
scope.class_eval do
|
8
|
-
delegate *Quandl::Client::Dataset::Data.forwardable_scope_methods, :to_h, to: :to_table, allow_nil: true
|
9
|
-
delegate *Quandl::Data.forwardable_methods, to: :to_table, allow_nil: true
|
10
|
-
end
|
11
|
-
|
12
|
-
scope *[:row, :rows, :limit, :offset, :accuracy, :column, :order,
|
13
|
-
:transform, :collapse, :exclude_headers]
|
14
|
-
|
15
|
-
scope :trim_start, ->(date){ date = parse_date(date); where( trim_start: date ) if date }
|
16
|
-
scope :trim_end, ->(date){ date = parse_date(date); where( trim_end: date ) if date }
|
17
|
-
|
18
|
-
scope_helper :parse_date, ->( value ){
|
19
|
-
begin
|
20
|
-
date = Date.jd(value.to_i) if value.kind_of?(String) && value.numeric?
|
21
|
-
date = Date.jd(value) if value.is_a?(Integer)
|
22
|
-
date = Date.parse(value) if value.is_a?(String) && value =~ /^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$/
|
23
|
-
date = value if value.is_a?(Date)
|
24
|
-
date = value.to_date if value.respond_to?(:to_date)
|
25
|
-
date.to_s
|
26
|
-
rescue
|
27
|
-
nil
|
28
|
-
end
|
29
|
-
}
|
30
|
-
|
31
|
-
scope_helper :to_table, -> {
|
32
|
-
data = fetch_once.data
|
33
|
-
data.headers = fetch_once.column_names
|
34
|
-
data
|
35
|
-
}
|
36
|
-
|
37
|
-
attributes :id, :limit, :collapse, :transformation, :trim_start, :trim_end,
|
38
|
-
:rows, :row, :frequency, :data, :from_date, :to_date, :column_names
|
39
|
-
|
40
|
-
def data
|
41
|
-
read_data
|
42
|
-
end
|
43
|
-
|
44
|
-
def data=(value)
|
45
|
-
write_data(value)
|
46
|
-
end
|
47
|
-
|
48
|
-
protected
|
49
|
-
|
50
|
-
def read_data
|
51
|
-
Quandl::Data.new( read_attribute(:data) )
|
52
|
-
end
|
53
|
-
|
54
|
-
def write_data(value )
|
55
|
-
write_attribute(:data, Quandl::Data.new(value).to_csv )
|
56
|
-
end
|
57
|
-
|
1
|
+
class Quandl::Client::Dataset::Data < Quandl::Client::Base
|
2
|
+
|
3
|
+
@_her_resource_path = "datasets/:id/data"
|
4
|
+
|
5
|
+
has_scope_composer
|
6
|
+
|
7
|
+
scope.class_eval do
|
8
|
+
delegate *Quandl::Client::Dataset::Data.forwardable_scope_methods, :to_h, to: :to_table, allow_nil: true
|
9
|
+
delegate *Quandl::Data.forwardable_methods, to: :to_table, allow_nil: true
|
10
|
+
end
|
11
|
+
|
12
|
+
scope *[:row, :rows, :limit, :offset, :accuracy, :column, :order,
|
13
|
+
:transform, :collapse, :exclude_headers]
|
14
|
+
|
15
|
+
scope :trim_start, ->(date){ date = parse_date(date); where( trim_start: date ) if date }
|
16
|
+
scope :trim_end, ->(date){ date = parse_date(date); where( trim_end: date ) if date }
|
17
|
+
|
18
|
+
scope_helper :parse_date, ->( value ){
|
19
|
+
begin
|
20
|
+
date = Date.jd(value.to_i) if value.kind_of?(String) && value.numeric?
|
21
|
+
date = Date.jd(value) if value.is_a?(Integer)
|
22
|
+
date = Date.parse(value) if value.is_a?(String) && value =~ /^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$/
|
23
|
+
date = value if value.is_a?(Date)
|
24
|
+
date = value.to_date if value.respond_to?(:to_date)
|
25
|
+
date.to_s
|
26
|
+
rescue
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
}
|
30
|
+
|
31
|
+
scope_helper :to_table, -> {
|
32
|
+
data = fetch_once.data
|
33
|
+
data.headers = fetch_once.column_names
|
34
|
+
data
|
35
|
+
}
|
36
|
+
|
37
|
+
attributes :id, :limit, :collapse, :transformation, :trim_start, :trim_end,
|
38
|
+
:rows, :row, :frequency, :data, :from_date, :to_date, :column_names
|
39
|
+
|
40
|
+
def data
|
41
|
+
read_data
|
42
|
+
end
|
43
|
+
|
44
|
+
def data=(value)
|
45
|
+
write_data(value)
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
def read_data
|
51
|
+
Quandl::Data.new( read_attribute(:data) )
|
52
|
+
end
|
53
|
+
|
54
|
+
def write_data(value )
|
55
|
+
write_attribute(:data, Quandl::Data.new(value).to_csv )
|
56
|
+
end
|
57
|
+
|
58
58
|
end
|
@@ -1,11 +1,11 @@
|
|
1
|
-
module Quandl
|
2
|
-
module Client
|
3
|
-
|
4
|
-
class Location < Quandl::Client::Base
|
5
|
-
|
6
|
-
attributes :id, :type, :scraper_url
|
7
|
-
|
8
|
-
end
|
9
|
-
|
10
|
-
end
|
1
|
+
module Quandl
|
2
|
+
module Client
|
3
|
+
|
4
|
+
class Location < Quandl::Client::Base
|
5
|
+
|
6
|
+
attributes :id, :type, :scraper_url
|
7
|
+
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
11
|
end
|
@@ -1,15 +1,15 @@
|
|
1
|
-
module Quandl
|
2
|
-
module Client
|
3
|
-
|
4
|
-
class Report < Quandl::Client::Base
|
5
|
-
|
6
|
-
###############
|
7
|
-
# VALIDATIONS #
|
8
|
-
###############
|
9
|
-
|
10
|
-
validates :message, presence: true
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
end
|
1
|
+
module Quandl
|
2
|
+
module Client
|
3
|
+
|
4
|
+
class Report < Quandl::Client::Base
|
5
|
+
|
6
|
+
###############
|
7
|
+
# VALIDATIONS #
|
8
|
+
###############
|
9
|
+
|
10
|
+
validates :message, presence: true
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
15
|
end
|
@@ -1,17 +1,17 @@
|
|
1
|
-
module Quandl
|
2
|
-
module Client
|
3
|
-
|
4
|
-
class Scraper < Quandl::Client::Base
|
5
|
-
|
6
|
-
attributes :id, :name, :scraper, :scraper_url, :git_url, :git_reference, :created_at, :updated_at, :type, :schedule_at
|
7
|
-
|
8
|
-
validates :name, presence: true
|
9
|
-
|
10
|
-
def scraper=(value)
|
11
|
-
write_attribute(:scraper, Faraday::UploadIO.new(value, 'text/plain') )
|
12
|
-
end
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
1
|
+
module Quandl
|
2
|
+
module Client
|
3
|
+
|
4
|
+
class Scraper < Quandl::Client::Base
|
5
|
+
|
6
|
+
attributes :id, :name, :scraper, :scraper_url, :git_url, :git_reference, :created_at, :updated_at, :type, :schedule_at
|
7
|
+
|
8
|
+
validates :name, presence: true
|
9
|
+
|
10
|
+
def scraper=(value)
|
11
|
+
write_attribute(:scraper, Faraday::UploadIO.new(value, 'text/plain') )
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
17
|
end
|
@@ -1,51 +1,51 @@
|
|
1
|
-
module Quandl
|
2
|
-
module Client
|
3
|
-
|
4
|
-
class Sheet < Quandl::Client::Base
|
5
|
-
|
6
|
-
##########
|
7
|
-
# SCOPES #
|
8
|
-
##########
|
9
|
-
|
10
|
-
scope :query, :page, :parent_url_title
|
11
|
-
|
12
|
-
|
13
|
-
################
|
14
|
-
# ASSOCIATIONS #
|
15
|
-
################
|
16
|
-
|
17
|
-
def parent
|
18
|
-
@parent ||= Quandl::Client::Sheet.find(parent_url_title)
|
19
|
-
end
|
20
|
-
|
21
|
-
def children
|
22
|
-
Quandl::Client::Sheet.parent_url_title(self.full_url_title)
|
23
|
-
end
|
24
|
-
|
25
|
-
|
26
|
-
###############
|
27
|
-
# VALIDATIONS #
|
28
|
-
###############
|
29
|
-
|
30
|
-
validates :title, presence: true
|
31
|
-
|
32
|
-
|
33
|
-
##############
|
34
|
-
# PROPERTIES #
|
35
|
-
##############
|
36
|
-
|
37
|
-
attributes :title, :content, :url_title, :full_url_title, :description, :skip_browse
|
38
|
-
|
39
|
-
def html
|
40
|
-
@html ||= self.attributes[:html] || Quandl::Client::Sheet.find(full_url_title).attributes[:html]
|
41
|
-
end
|
42
|
-
|
43
|
-
def parent_url_title
|
44
|
-
@parent_url_title ||= self.full_url_title.split('/')[0..-2].join()
|
45
|
-
end
|
46
|
-
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
1
|
+
module Quandl
|
2
|
+
module Client
|
3
|
+
|
4
|
+
class Sheet < Quandl::Client::Base
|
5
|
+
|
6
|
+
##########
|
7
|
+
# SCOPES #
|
8
|
+
##########
|
9
|
+
|
10
|
+
scope :query, :page, :parent_url_title
|
11
|
+
|
12
|
+
|
13
|
+
################
|
14
|
+
# ASSOCIATIONS #
|
15
|
+
################
|
16
|
+
|
17
|
+
def parent
|
18
|
+
@parent ||= Quandl::Client::Sheet.find(parent_url_title)
|
19
|
+
end
|
20
|
+
|
21
|
+
def children
|
22
|
+
Quandl::Client::Sheet.parent_url_title(self.full_url_title)
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
###############
|
27
|
+
# VALIDATIONS #
|
28
|
+
###############
|
29
|
+
|
30
|
+
validates :title, presence: true
|
31
|
+
|
32
|
+
|
33
|
+
##############
|
34
|
+
# PROPERTIES #
|
35
|
+
##############
|
36
|
+
|
37
|
+
attributes :title, :content, :url_title, :full_url_title, :description, :skip_browse
|
38
|
+
|
39
|
+
def html
|
40
|
+
@html ||= self.attributes[:html] || Quandl::Client::Sheet.find(full_url_title).attributes[:html]
|
41
|
+
end
|
42
|
+
|
43
|
+
def parent_url_title
|
44
|
+
@parent_url_title ||= self.full_url_title.split('/')[0..-2].join()
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
51
|
end
|
@@ -1,41 +1,49 @@
|
|
1
|
-
module Quandl
|
2
|
-
module Client
|
3
|
-
|
4
|
-
class Source < Quandl::Client::Base
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
#
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
1
|
+
module Quandl
|
2
|
+
module Client
|
3
|
+
|
4
|
+
class Source < Quandl::Client::Base
|
5
|
+
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def cached
|
9
|
+
@@cached ||= {}
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
##########
|
15
|
+
# SCOPES #
|
16
|
+
##########
|
17
|
+
|
18
|
+
scope :query
|
19
|
+
scope :page, ->(p){ where( page: p.to_i )}
|
20
|
+
scope :code, ->(c){ where( code: c.to_s.upcase )}
|
21
|
+
|
22
|
+
|
23
|
+
###############
|
24
|
+
# ASSOCIATIONS #
|
25
|
+
###############
|
26
|
+
|
27
|
+
def datasets
|
28
|
+
Quandl::Client::Dataset.source_code(code)
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
###############
|
33
|
+
# VALIDATIONS #
|
34
|
+
###############
|
35
|
+
|
36
|
+
validates :code, presence: true, length: { minimum: 2 }, format: { with: Quandl::Pattern.code, message: "is invalid. Expected format: #{Quandl::Pattern.code.to_example}" }
|
37
|
+
validates :host, :name, presence: true
|
38
|
+
|
39
|
+
|
40
|
+
##############
|
41
|
+
# PROPERTIES #
|
42
|
+
##############
|
43
|
+
|
44
|
+
attributes :code, :name, :host, :description, :datasets_count, :use_proxy, :type, :concurrency
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
41
49
|
end
|
@@ -1,60 +1,60 @@
|
|
1
|
-
class Quandl::Client::Superset < Quandl::Client::Base
|
2
|
-
|
3
|
-
scope :query, :page, :owner, :code, :source_code
|
4
|
-
|
5
|
-
attributes :id, :source_code, :code, :name, :urlize_name, :description, :updated_at, :private
|
6
|
-
attributes :column_codes, :column_names
|
7
|
-
attributes :frequency, :from_date, :to_date
|
8
|
-
|
9
|
-
validates :code, presence: true, format: { with: Quandl::Pattern.code, message: "is invalid. Expected format: #{Quandl::Pattern.code.to_example}" }
|
10
|
-
validates :column_codes, presence: true
|
11
|
-
validate :column_codes_should_be_valid!
|
12
|
-
|
13
|
-
def self.find_or_build( attributes={} )
|
14
|
-
record = self.find(attributes[:id]) if attributes[:id].present?
|
15
|
-
record = self.where( attributes.slice(:code, :source_code).merge( owner: 'myself' ) ).first unless record.try(:exists?)
|
16
|
-
record = self.new unless record.try(:exists?)
|
17
|
-
record.assign_attributes(attributes)
|
18
|
-
record
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.example
|
22
|
-
self.new( code: "SUPERSET_EXAMPLE", name: "Superset Name", description: "Superset description", column_codes: ['NSE.OIL.1'], column_names: ['Column Name'] )
|
23
|
-
end
|
24
|
-
|
25
|
-
def data
|
26
|
-
@data ||= Quandl::Client::Dataset::Data.with_id(id)
|
27
|
-
end
|
28
|
-
|
29
|
-
def full_url
|
30
|
-
File.join(Quandl::Client::Base.url.gsub(/api\/?/, ''), full_code)
|
31
|
-
end
|
32
|
-
|
33
|
-
def full_code
|
34
|
-
File.join(self.source_code.to_s, self.code.to_s)
|
35
|
-
end
|
36
|
-
|
37
|
-
protected
|
38
|
-
|
39
|
-
def column_codes_should_be_valid!
|
40
|
-
# must be an array
|
41
|
-
unless column_codes.respond_to?(:each)
|
42
|
-
# failure
|
43
|
-
self.errors.add( :column_codes, "expected an array, but got #{column_codes.class}.")
|
44
|
-
# nothing more to do
|
45
|
-
return false
|
46
|
-
end
|
47
|
-
# check each code
|
48
|
-
column_codes.each do |code|
|
49
|
-
# is the code valid?
|
50
|
-
next if code =~ /#{Quandl::Pattern.code}\.#{Quandl::Pattern.code}\.[0-9]+/
|
51
|
-
# otherwise report error
|
52
|
-
self.errors.add( :column_codes, "Code '#{code}' is invalid. Expected: /#{Quandl::Pattern.code.to_example}.#{Quandl::Pattern.code.to_example}.INTEGER/" )
|
53
|
-
# nothing more to do here
|
54
|
-
return false
|
55
|
-
end
|
56
|
-
# success
|
57
|
-
true
|
58
|
-
end
|
59
|
-
|
1
|
+
class Quandl::Client::Superset < Quandl::Client::Base
|
2
|
+
|
3
|
+
scope :query, :page, :owner, :code, :source_code
|
4
|
+
|
5
|
+
attributes :id, :source_code, :code, :name, :urlize_name, :description, :updated_at, :private
|
6
|
+
attributes :column_codes, :column_names
|
7
|
+
attributes :frequency, :from_date, :to_date
|
8
|
+
|
9
|
+
validates :code, presence: true, format: { with: Quandl::Pattern.code, message: "is invalid. Expected format: #{Quandl::Pattern.code.to_example}" }
|
10
|
+
validates :column_codes, presence: true
|
11
|
+
validate :column_codes_should_be_valid!
|
12
|
+
|
13
|
+
def self.find_or_build( attributes={} )
|
14
|
+
record = self.find(attributes[:id]) if attributes[:id].present?
|
15
|
+
record = self.where( attributes.slice(:code, :source_code).merge( owner: 'myself' ) ).first unless record.try(:exists?)
|
16
|
+
record = self.new unless record.try(:exists?)
|
17
|
+
record.assign_attributes(attributes)
|
18
|
+
record
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.example
|
22
|
+
self.new( code: "SUPERSET_EXAMPLE", name: "Superset Name", description: "Superset description", column_codes: ['NSE.OIL.1'], column_names: ['Column Name'] )
|
23
|
+
end
|
24
|
+
|
25
|
+
def data
|
26
|
+
@data ||= Quandl::Client::Dataset::Data.with_id(id)
|
27
|
+
end
|
28
|
+
|
29
|
+
def full_url
|
30
|
+
File.join(Quandl::Client::Base.url.gsub(/api\/?/, ''), full_code)
|
31
|
+
end
|
32
|
+
|
33
|
+
def full_code
|
34
|
+
File.join(self.source_code.to_s, self.code.to_s)
|
35
|
+
end
|
36
|
+
|
37
|
+
protected
|
38
|
+
|
39
|
+
def column_codes_should_be_valid!
|
40
|
+
# must be an array
|
41
|
+
unless column_codes.respond_to?(:each)
|
42
|
+
# failure
|
43
|
+
self.errors.add( :column_codes, "expected an array, but got #{column_codes.class}.")
|
44
|
+
# nothing more to do
|
45
|
+
return false
|
46
|
+
end
|
47
|
+
# check each code
|
48
|
+
column_codes.each do |code|
|
49
|
+
# is the code valid?
|
50
|
+
next if code =~ /#{Quandl::Pattern.code}\.#{Quandl::Pattern.code}\.[0-9]+/
|
51
|
+
# otherwise report error
|
52
|
+
self.errors.add( :column_codes, "Code '#{code}' is invalid. Expected: /#{Quandl::Pattern.code.to_example}.#{Quandl::Pattern.code.to_example}.INTEGER/" )
|
53
|
+
# nothing more to do here
|
54
|
+
return false
|
55
|
+
end
|
56
|
+
# success
|
57
|
+
true
|
58
|
+
end
|
59
|
+
|
60
60
|
end
|