datasift 3.0.0.beta4 → 3.0.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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/CHANGELOG.md +12 -0
  4. data/LICENSE +1 -1
  5. data/MIGRATING_TO_V.3.0.0.md +1 -1
  6. data/README.md +23 -2
  7. data/Rakefile +10 -0
  8. data/VERSION +1 -1
  9. data/datasift.gemspec +4 -4
  10. data/examples/auth.rb +14 -10
  11. data/examples/cli.sh +2 -2
  12. data/examples/core_api_eg.rb +6 -1
  13. data/examples/dynamic_list_eg.rb +74 -0
  14. data/examples/dynamic_list_replace_eg.rb +45 -0
  15. data/examples/historics_eg.rb +20 -13
  16. data/examples/historics_preview_eg.rb +5 -4
  17. data/examples/live_stream_eg.rb +2 -1
  18. data/examples/managed_source_eg.rb +11 -10
  19. data/examples/pull.rb +8 -8
  20. data/examples/push_eg.rb +32 -15
  21. data/lib/cli.rb +2 -2
  22. data/lib/datasift.rb +7 -3
  23. data/lib/dynamic_list.rb +66 -0
  24. data/lib/dynamic_list_replace.rb +45 -0
  25. data/lib/historics.rb +17 -0
  26. data/lib/historics_preview.rb +2 -1
  27. data/lib/push.rb +10 -17
  28. data/test/datasift/core_api_test.rb +153 -0
  29. data/test/datasift/historics_preview_api_test.rb +83 -0
  30. data/test/datasift/push_api_test.rb +223 -0
  31. data/test/fixtures/balance.json +1 -0
  32. data/test/fixtures/compile_csdl_invalid.json +1 -0
  33. data/test/fixtures/compile_csdl_valid.json +1 -0
  34. data/test/fixtures/dpu_valid.json +1 -0
  35. data/test/fixtures/preview_create_valid.json +1 -0
  36. data/test/fixtures/preview_get_running.json +1 -0
  37. data/test/fixtures/preview_get_succeeded.json +1 -0
  38. data/test/fixtures/push_create_valid.json +1 -0
  39. data/test/fixtures/push_get_list_by_hash_valid.json +1 -0
  40. data/test/fixtures/push_get_list_by_historics_id_valid.json +1 -0
  41. data/test/fixtures/push_get_list_valid.json +1 -0
  42. data/test/fixtures/push_get_valid.json +1 -0
  43. data/test/fixtures/push_log_valid.json +1 -0
  44. data/test/fixtures/push_pause_valid.json +1 -0
  45. data/test/fixtures/push_stop_valid.json +1 -0
  46. data/test/fixtures/push_validate_valid.json +1 -0
  47. data/test/fixtures/usage_current.json +1 -0
  48. data/test/fixtures/validate_csdl_invalid.json +1 -0
  49. data/test/fixtures/validate_csdl_valid.json +1 -0
  50. data/test/test_helper.rb +17 -0
  51. metadata +36 -9
  52. data/tests/core_api_test.rb +0 -95
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f5a8e4b6cddffbd3b5608c4fe831bdf87213c772
4
- data.tar.gz: e05742fa5831660e60c8395b812025d40bbdf0dd
3
+ metadata.gz: 92d16d17339dcc890c88002c7f23576e2a6adf3d
4
+ data.tar.gz: 3759590fac485d84ec8e7cddc4a6fec799972afa
5
5
  SHA512:
6
- metadata.gz: 0a03568fe8b5bc5a650b8694f3763154ffd0c10fd13924221dc29cadfcc3befdd5a68b4ae325817c39fa84aea1b84946111230f3f73363d4682ae45f4e1445f9
7
- data.tar.gz: f626e022353a188ba41d76d68680bacb60c92bd716921362c5c51400efbbe876ac6313b93caf7e7d9b1463bc53f4a4a339b11167ee781af34ca3cb7840b7c5a1
6
+ metadata.gz: c4afb552f393f501c954f0f148a5bb95ff070a52656838d1bf49a3b5188f679a0b38c8a51dde3d413c6d2ab3fc8c54a251c20fd7ec9855446ffb294326965577
7
+ data.tar.gz: ed4fb2feef7cabfc0534a35e2b5fb475c74be79b319bb7f6d6a6e1c443c8405654ccc06e1c6c596e0a73250518da7c45023a2657ebe65d8e449cd748d2c1c23a
data/.gitignore CHANGED
@@ -5,3 +5,5 @@ sftp-config.json
5
5
  rdoc/
6
6
  .bundle/
7
7
  Gemfile.lock
8
+ coverage/*
9
+ TODO
data/CHANGELOG.md CHANGED
@@ -1,6 +1,18 @@
1
1
  CHANGELOG
2
2
  ================================
3
3
 
4
+ v.3.0.0 (2014-07-04)
5
+ --------------------
6
+
7
+ Final fixes for v.3.0.0!
8
+ This release does break backwards compatibility with version 2.x and earlier. A [migration guide](https://github.com/datasift/datasift-ruby/blob/3.0.0/MIGRATING_TO_V.3.0.0.md) is available.
9
+ * Adds support for the [Pull Push Destination](http://dev.datasift.com/docs/push/connectors/pull)
10
+ * Adds support for DataSift [Historics Preview](http://dev.datasift.com/docs/historics/preview)
11
+ * Adds support for the new Dynamic Lists feature
12
+ * Adds support for multi-streaming via WebSockets
13
+ * Added a CLI to the library
14
+ * Updated test suite
15
+
4
16
  v.3.0.0.beta (2013-11-07)
5
17
  -------------------------
6
18
 
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011-2012 MediaSift Ltd
1
+ Copyright (c) 2011-2014 MediaSift Ltd
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
@@ -109,7 +109,7 @@ on_message is called when we receive [user status messages](http://dev.datasift.
109
109
  * @datasift.push.update @params.merge({:id => subscription_id, :name => 'Updated name'})
110
110
  * @datasift.push.stop subscription_id
111
111
  * @datasift.push.delete subscription_id
112
- * @datasift.push.logs
112
+ * @datasift.push.log
113
113
  * @datasift.push.get_by_subscription subscription_id
114
114
  * @datasift.push.get
115
115
  * @datasift.pull
data/README.md CHANGED
@@ -20,6 +20,14 @@ The library will use SSL connections by default. While we recommend using SSL
20
20
  you may disable it if required by passing ':enable_ssl => false' as the third
21
21
  parameter when creating your @config object.
22
22
 
23
+ Getting Started
24
+ ---------------
25
+ Before you can begin using this library, you will need to have an active [DataSift](http://datasift.com) account - you can sign up for a new account at [datasift.com/get-started](http://datasift.com/get-started/).
26
+
27
+ Many of the examples and API endpoints used in this library require you have enabled certain data sources before you can receive any data (you should do this at [datasift.com/source](https://datasift.com/source)). Certain API features, such as [Historics](http://datasift.com/platform/historics/) and [Managed Sources](http://datasift.com/platform/datasources/) will require you have signed up to a monthly subscription before you can access them.
28
+
29
+ If you are interested in using these features, or would like more information about DataSift, please [get in touch](http://datasift.com/contact-us/)!
30
+
23
31
  Simple example
24
32
  --------------
25
33
 
@@ -65,10 +73,23 @@ conn.stream.read_thread.join
65
73
  See the [Understanding the Output Data](http://dev.datasift.com/docs/getting-started/data) page on the DataSift Developer site for
66
74
  full details of the data contained within each interaction.
67
75
 
76
+ Supported Operating Environment
77
+ -------------------------------
78
+ This version of the client library has been tested, and is known to work against the following language versions and Operating Systems:
79
+
80
+ ### Language Versions
81
+ * Ruby 2.0.0
82
+ * Ruby 2.1.0
83
+
84
+ ### Operating Systems
85
+ * Linux
86
+ * OS X
87
+ * Windows 7/8
88
+
68
89
  License
69
90
  -------
70
91
 
71
- All code contained in this repository is Copyright 2011-2013 MediaSift Ltd.
92
+ All code contained in this repository is Copyright 2011-2014 MediaSift Ltd.
72
93
 
73
- This code is released under the BSD license. Please see the LICENSE file for
94
+ This code is released under the BSD license. Please see the [LICENSE](https://github.com/datasift/datasift-ruby/blob/master/LICENSE) file for
74
95
  more details.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new(:test) do |test|
5
+ test.libs << 'lib' << 'test'
6
+ test.pattern = 'test/**/*.rb'
7
+ test.verbose = true
8
+ end
9
+
10
+ task :default => :test
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.0.0.beta4
1
+ 3.0.0
data/datasift.gemspec CHANGED
@@ -8,19 +8,19 @@ Gem::Specification.new do |s|
8
8
  s.homepage = 'https://github.com/datasift/datasift-ruby'
9
9
  s.license = 'BSD'
10
10
 
11
- s.platform = Gem::Platform::RUBY
12
- s.rubygems_version = %q{1.3.6}
11
+ s.platform = Gem::Platform::RUBY
13
12
  s.required_rubygems_version = Gem::Requirement.new(">= 1.3.6") if s.respond_to? :required_rubygems_version=
14
13
 
15
14
  s.add_runtime_dependency('rest-client', '~> 1.6.7')
16
15
  s.add_runtime_dependency('multi_json', '~> 1.8.0')
17
16
  s.add_runtime_dependency('websocket-td', '~> 0.0.4')
17
+
18
18
  s.add_development_dependency('rdoc', '> 0')
19
19
  s.add_development_dependency('webmock', '~> 1.17.1')
20
20
  s.add_development_dependency('shoulda', '~> 2.11.3')
21
- s.add_development_dependency('test-unit', '>= 2.5.5')
21
+ s.add_development_dependency('minitest', '~> 5.0')
22
22
 
23
23
  s.files = `git ls-files`.split("\n")
24
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
+ s.test_files = `git ls-files -- {test}/*`.split("\n")
25
25
  s.require_paths = ["lib"]
26
26
  end
data/examples/auth.rb CHANGED
@@ -1,25 +1,29 @@
1
1
  class DataSiftExample
2
- require '../lib/datasift'
2
+ require 'datasift'
3
3
 
4
4
  def initialize
5
5
  #only SSLv3 and TLSv1 currently supported, TLSv1 preferred
6
6
  # this is fixed in REST client and is scheduled for the 1.7.0 release
7
7
  # see https://github.com/rest-client/rest-client/pull/123
8
8
  OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:ssl_version] = 'TLSv1'
9
- @username = 'zcourts'
10
- @api_key ='9dc2e16075de005b1a23444fbc6dd269'
11
- @config ={:username => @username, :api_key => @api_key, :enable_ssl => true}
9
+ @username = 'DATASIFT_USERNAME'
10
+ @api_key = 'DATASIFT_API_KEY'
11
+ @config = {:username => @username, :api_key => @api_key, :enable_ssl => true}
12
12
  @params = {
13
13
  :output_type => 's3',
14
- 'output_params.bucket' => 'apitests',
14
+ 'output_params.bucket' => 'YOUR_BUCKET_NAME',
15
15
  'output_params.directory' => 'ruby',
16
16
  'output_params.acl' => 'private',
17
- 'output_params.auth.access_key' => 'AKIAIINK5C4FH75RSWNA',
18
- 'output_params.auth.secret_key' => 'F9mLnLoFFGuCNgbMUhdhHmm5YCcNAt/OG32SUhPy',
17
+ 'output_params.auth.access_key' => 'ADD_YOUR_ACCESS_KEY',
18
+ 'output_params.auth.secret_key' => 'ADD_YOUR_SECRET_KEY',
19
19
  'output_params.delivery_frequency' => 0,
20
- 'output_params.max_size' => 10485760,
20
+ 'output_params.max_size' => 104857600,
21
21
  'output_params.file_prefix' => 'DataSift',
22
22
  }
23
+ @pull_params = {
24
+ :output_type => 'pull',
25
+ 'output_params.max_size' => 52428800
26
+ }
23
27
  @datasift = DataSift::Client.new(@config)
24
28
  end
25
29
 
@@ -27,12 +31,12 @@ class DataSiftExample
27
31
 
28
32
  def create_push(hash, is_historics_id = false)
29
33
  create_params = @params.merge ({
30
- #hash or playback_id can be used but not both
34
+ #hash or historics_id can be used but not both
31
35
  :name => 'My awesome push subscription',
32
36
  :initial_status => 'active', # or 'paused' or 'waiting_for_start'
33
37
  })
34
38
  if is_historics_id
35
- create_params.merge!({:playback_id => hash})
39
+ create_params.merge!({:historics_id => hash})
36
40
  else
37
41
  create_params.merge!({:hash => hash,
38
42
  #start and end are not valid for historics
data/examples/cli.sh CHANGED
@@ -48,7 +48,7 @@ historic_id=$(echo ${historic} | jq -r .body.id)
48
48
  echo "Historic created with ID $historic_id"
49
49
 
50
50
  echo 'Validating Push subscription'
51
- push_v=$(ds -e push -c validate -p playback_id ${historic_id} -p name "Playback CLI @ $start" -p output_type http \
51
+ push_v=$(ds -e push -c validate -p historics_id ${historic_id} -p name "Playback CLI @ $start" -p output_type http \
52
52
  -p output_params.method post -p output_params.url 'http://ec2-50-19-63-138.compute-1.amazonaws.com:80' \
53
53
  -p output_params.delivery_frequency 0 -p output_params.max_size 102400 -p output_params.auth.type none \
54
54
  -p output_params.verify_ssl false -p output_params.use_gzip true)
@@ -61,7 +61,7 @@ if [ ${push_status} != 200 ]; then
61
61
  fi
62
62
 
63
63
  echo 'Creating Push from Historic'
64
- push=$(ds -e push -c create -p playback_id ${historic_id} -p name "Playback CLI @ $start" -p output_type http \
64
+ push=$(ds -e push -c create -p historics_id ${historic_id} -p name "Playback CLI @ $start" -p output_type http \
65
65
  -p output_params.method post -p output_params.url 'http://ec2-50-19-63-138.compute-1.amazonaws.com:80' \
66
66
  -p output_params.delivery_frequency 0 -p output_params.max_size 102400 -p output_params.auth.type none \
67
67
  -p output_params.verify_ssl false -p output_params.use_gzip true)
@@ -10,21 +10,26 @@ class CoreApiEg < DataSiftExample
10
10
  begin
11
11
  csdl = 'interaction.content contains "test"'
12
12
  # see docs at http://dev.datasift.com/docs/rest-api/validate
13
+ puts "Is the following CSDL valid? #{csdl}"
13
14
  puts @datasift.valid? csdl
14
15
 
15
16
  # http://dev.datasift.com/docs/rest-api/compile
17
+ puts "\nCompile the CSDL and get a stream hash"
16
18
  stream = @datasift.compile csdl
17
19
  puts stream[:data][:hash]
18
20
 
19
21
  # http://dev.datasift.com/docs/rest-api/dpu
22
+ puts "\nGet the DPU cost of the compiled CSDL"
20
23
  dpu = @datasift.dpu stream[:data][:hash]
21
24
  puts dpu[:data][:dpu]
22
25
 
23
26
  # http://dev.datasift.com/docs/rest-api/balance
27
+ puts "\nGet the remaining balance for my account"
24
28
  balance = @datasift.balance
25
29
  puts balance[:data]
26
30
 
27
31
  #http://dev.datasift.com/docs/rest-api/usage
32
+ puts "\nGet my recent account usage"
28
33
  usage = @datasift.usage
29
34
  puts usage[:data]
30
35
 
@@ -43,4 +48,4 @@ class CoreApiEg < DataSiftExample
43
48
  end
44
49
  end
45
50
  end
46
- CoreApiEg.new
51
+ CoreApiEg.new
@@ -0,0 +1,74 @@
1
+ require './auth'
2
+
3
+ class DynamicListApi < DataSiftExample
4
+ def initialize
5
+ super
6
+ run
7
+ end
8
+
9
+ def run
10
+ begin
11
+
12
+ ##
13
+ # Text Dynamic Lists
14
+ puts "\nCreating a Dynamic List containing text items"
15
+ puts 'Creating a dynamic list: /list/create'
16
+ list = @datasift.dynamic_list.create('text', 'My dynamic list')
17
+ puts list
18
+
19
+ id = list[:data][:id]
20
+ items = ['keyword1', 'keyword2']
21
+
22
+ puts "\nGet a list of your Dynamic Lists: /list/get"
23
+ puts @datasift.dynamic_list.get
24
+
25
+ puts "\nAdding items to the dynamic list: #{items}: /list/add"
26
+ puts @datasift.dynamic_list.add(id, items)
27
+
28
+ csdl = "interaction.content list_any \"#{id}\""
29
+ puts "\nCompile the following CSDL using a Dynamic List:"
30
+ puts csdl
31
+ puts @datasift.compile csdl
32
+
33
+ remove_items = ['keyword1']
34
+ puts "\nRemoving item #{remove_items} from the dynamic list: /list/remove"
35
+ puts @datasift.dynamic_list.remove(id, remove_items)
36
+
37
+ puts "\nCheck #{remove_items} has been removed from the list: /list/exists"
38
+ puts @datasift.dynamic_list.exists(id, remove_items)
39
+
40
+ remaining_item = ['keyword2']
41
+ puts "\nCheck #{remaining_item} still exists in the list: /list/exists"
42
+ puts @datasift.dynamic_list.exists(id, remaining_item)
43
+
44
+ puts "\nDeleting the list: /list/delete"
45
+ puts @datasift.dynamic_list.delete id
46
+
47
+ ##
48
+ # Integer Dynamic Lists
49
+ puts "\n --- \nCreating a Dynamic List containing integers"
50
+ puts 'Creating a dynamic list: /list/create'
51
+ list = @datasift.dynamic_list.create('integer', 'My dynamic integer list')
52
+ puts list
53
+
54
+ id = list[:data][:id]
55
+ items = [11111, 22222, 33333, 44444]
56
+
57
+ puts "\nAdding integers to the dynamic list: #{items}: /list/add"
58
+ puts @datasift.dynamic_list.add(id, items)
59
+
60
+ csdl = "interaction.author.id list_in \"#{id}\""
61
+ puts "\nCompile the following CSDL using a Dynamic List:"
62
+ puts csdl
63
+ puts @datasift.compile csdl
64
+
65
+ puts "\nDeleting the list: /list/delete"
66
+ puts @datasift.dynamic_list.delete id
67
+
68
+ rescue DataSiftError => dse
69
+ puts dse.message
70
+ end
71
+ end
72
+ end
73
+
74
+ DynamicListApi.new
@@ -0,0 +1,45 @@
1
+ require './auth'
2
+
3
+ class DynamicListReplaceApi < DataSiftExample
4
+ def initialize
5
+ super
6
+ run
7
+ end
8
+
9
+ def run
10
+ begin
11
+
12
+ puts "\nCreating a dynamic list: /list/create"
13
+ list = @datasift.dynamic_list.create('text', 'My dynamic list')
14
+ puts list
15
+
16
+ id = list[:data][:id]
17
+
18
+ puts "\nStart a new replace list: /list/replace/start"
19
+ replace = @datasift.dynamic_list_replace.start id
20
+ puts replace
21
+
22
+ puts "\nAbort the list replace: /list/replace/abort"
23
+ puts @datasift.dynamic_list_replace.abort replace[:data][:id]
24
+
25
+ puts "\nStart a new replace list (again): /list/replace/start"
26
+ replace = @datasift.dynamic_list_replace.start id
27
+ puts replace
28
+
29
+ items = ['keyword1', 'keyword2']
30
+ puts "\nAdd items #{items} to replacement list: /list/replace/add"
31
+ puts @datasift.dynamic_list_replace.add(replace[:data][:id], items)
32
+
33
+ puts "\nCommit the replacement list: /list/replace/commit"
34
+ puts @datasift.dynamic_list_replace.commit replace[:data][:id]
35
+
36
+ puts "\nCleanup: Delete the list: /list/delete"
37
+ puts @datasift.dynamic_list.delete id
38
+
39
+ rescue DataSiftError => dse
40
+ puts dse.message
41
+ end
42
+ end
43
+ end
44
+
45
+ DynamicListReplaceApi.new
@@ -9,42 +9,49 @@ class HistoricsApi < DataSiftExample
9
9
  begin
10
10
  stream = @datasift.compile 'interaction.content contains "datasift"'
11
11
  hash = stream[:data][:hash]
12
- start = Time.now.to_i - 7200
12
+ start = Time.now.to_i - 10800
13
13
  end_time = start + 3600
14
14
 
15
- puts 'Check the data coverage for the last two hours'
15
+ puts 'Check the data coverage for this Historic period'
16
16
  puts @datasift.historics.status(start, end_time)
17
17
 
18
- puts 'Preparing'
19
- #prepare a historics to start from two hours ago and run for 1 hour using twitter as a data source and using only a 10% sample
20
- historics = @datasift.historics.prepare(hash, start, end_time, 'My ruby historics')
18
+ puts "\nPreparing"
19
+ #prepare a historics to start from three hours ago and run for 1 hour using twitter as a data source and using only a 10% sample
20
+ historics = @datasift.historics.prepare(hash, start, end_time, 'My ruby historics', 'twitter', 10)
21
21
  puts historics
22
22
 
23
23
  id = historics[:data][:id]
24
24
 
25
- puts 'Creating push subscription for historics'
25
+ puts "\nCreating push subscription for historics"
26
26
  puts create_push(id, true)
27
27
 
28
- puts "Starting historics #{id}"
28
+ puts "\nStarting historics #{id}"
29
29
  puts @datasift.historics.start id
30
30
 
31
- puts 'Updating historics'
31
+ puts "\nPausing historics #{id}"
32
+ puts @datasift.historics.pause id
33
+
34
+ puts "\nResuming historics #{id}"
35
+ puts @datasift.historics.resume id
36
+
37
+ puts "\nUpdating historics"
32
38
  puts @datasift.historics.update(id, 'The new name of my historics')
33
39
 
34
- puts 'Get info for the historics'
40
+ puts "\nGet info for the historics"
35
41
  puts @datasift.historics.get_by_id id
36
42
 
37
- puts 'Getting info for all my historics'
43
+ puts "\nGetting info for all my historics"
38
44
  puts @datasift.historics.get
39
45
 
40
- puts 'Stopping historics'
46
+ puts "\nStopping historics"
41
47
  puts @datasift.historics.stop id
42
48
 
43
- puts 'Deleting historics'
49
+ puts "\nDeleting historics"
44
50
  puts @datasift.historics.delete id
45
51
  rescue DataSiftError => dse
46
52
  puts dse.message
47
53
  end
48
54
  end
49
55
  end
50
- HistoricsApi.new
56
+
57
+ HistoricsApi.new
@@ -11,14 +11,15 @@ class HistoricsPreviewApi < DataSiftExample
11
11
  stream = @datasift.compile 'interaction.content contains "datasift"'
12
12
  hash = stream[:data][:hash]
13
13
 
14
- puts 'Creating a preview'
14
+ puts "\nCreating a preview"
15
15
  # see http://dev.datasift.com/docs/rest-api/previewcreate for docs
16
+ sources = 'facebook,twitter'
16
17
  parameters = 'interaction.author.link,targetVol,hour;interaction.type,freqDist,10'
17
18
  start = Time.now.to_i - (3600 * 48) # 48hrs ago
18
- source = @datasift.historics_preview.create(hash, parameters, start)
19
+ source = @datasift.historics_preview.create(hash, sources, parameters, start)
19
20
  puts source
20
21
 
21
- puts 'Getting preview data'
22
+ puts "\nGetting preview data"
22
23
  puts @datasift.historics_preview.get source[:data][:id]
23
24
 
24
25
  rescue DataSiftError => dse
@@ -27,4 +28,4 @@ class HistoricsPreviewApi < DataSiftExample
27
28
  end
28
29
  end
29
30
 
30
- HistoricsPreviewApi.new
31
+ HistoricsPreviewApi.new