Comparing version 0.4.0 to 1.2.0
432
index.js
@@ -1,270 +0,166 @@ | ||
var _ = require('lodash') | ||
var needle = require('needle') | ||
var config = require('./lib/config'); | ||
var token = require('./lib/token'); | ||
var tag = require('./lib/tag'); | ||
var info = require('./lib/info'); | ||
var languages = require('./lib/languages'); | ||
var callback = require('./lib/callback'); | ||
var color = require('./lib/color'); | ||
var feedback = require('./lib/feedback'); | ||
var usage = require('./lib/usage'); | ||
var _array = function(str) { | ||
if (_.isArray(str)) { | ||
return str | ||
} else { | ||
return [str] | ||
module.exports = global.Clarifai = { | ||
initialize: function(options) { | ||
config.set('apiEndpoint', options.apiEndpoint || process.env.API_ENDPOINT || 'https://api.clarifai.com'); | ||
config.set('clientId', options.clientId || process.env.CLIENT_ID); | ||
config.set('clientSecret', options.clientSecret || process.env.CLIENT_SECRET); | ||
token.delete(); | ||
}, | ||
/** | ||
* Gets a token from the API using client credentials | ||
* @method getToken | ||
* @param {Function} callback A node-style calback function that accepts err, token (optional) | ||
* @return {Promise(token, error} A Promise that is fulfilled with the token string or rejected with an error | ||
*/ | ||
getToken: function(_callback) { | ||
var promise = token.get(); | ||
callback.handle(promise, _callback); | ||
return promise; | ||
}, | ||
/** | ||
* Sets the token to use for the API | ||
* @method setToken | ||
* @param {String} _token The token you are setting | ||
* @return {Boolean} true if token has valid fields, false if not | ||
*/ | ||
setToken: function(_token) { | ||
return token.set(_token); | ||
}, | ||
/** | ||
* Deletes the token | ||
* @method deleteToken | ||
*/ | ||
deleteToken: function() { | ||
token.delete(); | ||
}, | ||
/** | ||
* Gets tags given a url | ||
* @method getTagsByUrl | ||
* @param {String} or {Array} url A publicly accessible url of the image. | ||
* @param {Object} options Object with keys explained below: (optional) | ||
* @param {String} model The model used to tag the image (optional) | ||
* @param {String} language The language used to tag the image (optional) | ||
* @param {String} or {Array} selectClasses Restrict the tags returned | ||
* @param {String} or {Array} localId Provide a localId for each url to simplify tracking requests (optional) | ||
* @param {Function} A node-style calback function that accepts err, token (optional) | ||
* @return {Promise(token, error} A Promise that is fulfilled with the API response or rejected with an error | ||
*/ | ||
getTagsByUrl: function(url, options, _callback) { | ||
var callbackFn = _callback; | ||
if ( typeof options === 'function' ) { | ||
callbackFn = options; | ||
}; | ||
var promise = tag.getByUrl(url, options); | ||
callback.handle(promise, callbackFn); | ||
return promise; | ||
}, | ||
/** | ||
* Gets tags given image bytes | ||
* @method getTagsByImageBytes | ||
* @param {String} image bytes Base64 encoded image bytes. | ||
* @param {Object} options Object with keys explained below: (optional) | ||
* @param {String} model The model used to tag the image (optional) | ||
* @param {String} language The language used to tag the image (optional) | ||
* @param {String} or {Array} selectClasses Restrict the tags returned | ||
* @param {String} or {Array} localId Provide a localId for each url to simplify tracking requests (optional) | ||
* @param {Function} A node-style calback function that accepts err, token (optional) | ||
* @return {Promise(token, error} A Promise that is fulfilled with the API response or rejected with an error | ||
*/ | ||
getTagsByImageBytes: function(imageBytes, options, _callback) { | ||
var callbackFn = _callback; | ||
if ( typeof options === 'function' ) { | ||
callbackFn = options; | ||
}; | ||
var promise = tag.getByImageBytes(imageBytes, options); | ||
callback.handle(promise, callbackFn); | ||
return promise; | ||
}, | ||
/** | ||
* Gets API info | ||
* @method getInfo | ||
* @param {Function} callback A node-style calback function that accepts err, token (optional) | ||
* @return {Promise(token, error} A Promise that is fulfilled with the API response or rejected with an error | ||
*/ | ||
getInfo: function(_callback) { | ||
var promise = info.get(); | ||
callback.handle(promise, _callback); | ||
return promise; | ||
}, | ||
/** | ||
* Gets languages supported by the API | ||
* @method getLanguages | ||
* @param {Function} callback A node-style calback function that accepts err, token (optional) | ||
* @return {Promise(token, error} A Promise that is fulfilled with the API response or rejected with an error | ||
*/ | ||
getLanguages: function(_callback) { | ||
var promise = languages.get(); | ||
callback.handle(promise, _callback); | ||
return promise; | ||
}, | ||
/** | ||
* Gets colors given a url | ||
* @method getColorByUrl | ||
* @param {String} or {Array} url A publicly accessible url of the image. | ||
* @param {Function} A node-style calback function that accepts err, token (optional) | ||
* @return {Promise(token, error} A Promise that is fulfilled with the API response or rejected with an error | ||
*/ | ||
getColorsByUrl: function(url, _callback) { | ||
var promise = color.getByUrl(url); | ||
callback.handle(promise, _callback); | ||
return promise; | ||
}, | ||
/** | ||
* Gets colors given image bytes | ||
* @method getColorsByImageBytes | ||
* @param {String} url A publicly accessible url of the image. | ||
* @param {Function} A node-style calback function that accepts err, token (optional) | ||
* @return {Promise(token, error} A Promise that is fulfilled with the API response or rejected with an error | ||
*/ | ||
getColorsByImageBytes: function(imageBytes, _callback) { | ||
var promise = color.getByImageBytes(imageBytes); | ||
callback.handle(promise, _callback); | ||
return promise; | ||
}, | ||
/** | ||
* Gets API usage | ||
* @method getUsage | ||
* @param {Function} callback A node-style calback function that accepts err, token (optional) | ||
* @return {Promise(token, error} A Promise that is fulfilled with the API response or rejected with an error | ||
*/ | ||
getUsage: function(_callback) { | ||
var promise = usage.get(); | ||
callback.handle(promise, _callback); | ||
return promise; | ||
}, | ||
/** | ||
* Provide feedback for a url or list of urls | ||
* @method createFeedback | ||
* @param {String} or {Array} url A publicly accessible url of the image. | ||
* @param {Object} options Object with keys explained below: (optional) | ||
* @param {String} or {Array} addTags Add additional tags that are relevant to the given image(s) (optional) | ||
* @param {String} or {Array} removeTags Remove tags that are not relevant to the given image(s) (optional) | ||
* @param {String} or {Array} similarUrls Tell the system two or more images are similar (optional) | ||
* @param {String} or {Array} disSimilarUrls Tell the system two or more images are dissimilar (optional) | ||
* @param {String} or {Array} searchClick Tell the system that the search result was relevant to the query (optional) | ||
* @param {Function} A node-style calback function that accepts err, token (optional) | ||
* @return {Promise(token, error} A Promise that is fulfilled with the API response or rejected with an error | ||
*/ | ||
createFeedback: function(url, options, _callback) { | ||
var callbackFn = _callback; | ||
if ( typeof options === 'function' ) { | ||
callbackFn = options; | ||
}; | ||
var promise = feedback.create(url, options); | ||
callback.handle(promise, callbackFn); | ||
return promise; | ||
} | ||
} | ||
var _encodeTagUrls = function (urls, lang) { | ||
var data = '' | ||
for (var url of _array(urls)) { | ||
data += encodeURI('url=' + url) + '&' | ||
} | ||
if (lang) { | ||
data += 'language=' + lang | ||
} | ||
return data | ||
} | ||
var _boundary = 'clarifai_multipart_boundary' | ||
var _partForParameter = function(name, value) { | ||
var part = '--' + _boundary + '\r\nContent-Disposition: form-data; name="' + name + '"\r\n\r\n' + value + '\r\n' | ||
return new Buffer(part, 'utf8'); | ||
} | ||
var _buildMultipart = function(buffers, lang) { | ||
// Build a multipart payload. We can't use needle's support for this because needle expects all | ||
// parts to have distinct names while Clarifai requires multiple parts to have the same name. | ||
var chunks = [] | ||
for (var buffer of _array(buffers)) { | ||
var header = '--' + _boundary + '\r\n' + | ||
'Content-Disposition: form-data; name="encoded_data"; filename="data"\r\n' + | ||
'Content-Transfer-Encoding: binary\r\n' + | ||
'Content-Type: application/octet-stream\r\n\r\n' | ||
chunks.push(new Buffer(header, 'ascii')) | ||
chunks.push(buffer) | ||
} | ||
if (lang) { | ||
chunks.push(_partForParameter('language', lang)) | ||
} | ||
chunks.push(new Buffer('--' + _boundary + '--\r\n', 'ascii')) | ||
return Buffer.concat(chunks) | ||
} | ||
var _parseErr = function(err, resp, body, cb) { | ||
if(err) { | ||
return cb(err) | ||
} else if((resp.statusCode !== 200 && resp.statusCode !== 201) || body.status_code === 'PARTIAL_ERROR') { | ||
return cb(body) | ||
} else { | ||
return cb(err, body) | ||
} | ||
} | ||
var _withAccessToken = function(_this, options) { | ||
return _.merge(options, { headers: { 'Authorization': _this.tokenType + ' ' + _this.accessToken }}); | ||
} | ||
var _request = function(verb, type, data, options, _this, cb) { | ||
var url = 'https://api.clarifai.com' | ||
switch(type) { | ||
case 'feedback': | ||
url += '/v1/feedback/' | ||
break | ||
case 'info': | ||
url += '/v1/info/' | ||
break | ||
case 'tag': | ||
url += '/v1/tag/' | ||
break | ||
case 'token': | ||
url += '/v1/token/' | ||
break | ||
default: | ||
throw err('Request Type not defined') | ||
} | ||
needle.request(verb, url, data, _withAccessToken(_this, options), function(err, resp, body) { | ||
if (body.status_code === 'TOKEN_INVALID' || body.status_code === 'TOKEN_NONE') { | ||
_this.getAccessToken(function(err) { | ||
if(err) { | ||
return cb(err) | ||
} else { | ||
needle.request(verb, url, data, _withAccessToken(_this, options), function(err, resp, body) { | ||
_parseErr(err, resp, body, cb) | ||
}) | ||
} | ||
}) | ||
} else { | ||
_parseErr(err, resp, body, cb) | ||
} | ||
}) | ||
} | ||
var formatImageResults = function(body) { | ||
var results = body.results | ||
results = _.map(results, function(result) { | ||
var tagResults = _.zip(result.result.tag.classes, result.result.tag.concept_ids, result.result.tag.probs) | ||
var tags = _.map(tagResults, function(tag) { | ||
return { | ||
class: tag[0], | ||
conceptId: tag[1], | ||
probability: tag[2] | ||
} | ||
}) | ||
var ret = { | ||
docId: result.docid, | ||
docIdStr: result.docid_str, | ||
tags: tags | ||
} | ||
return ret | ||
}) | ||
if (results.length < 2) { | ||
results = _.first(results) | ||
} | ||
return results | ||
} | ||
var formatVideoResults = function(body) { | ||
var results = body.results | ||
results = _.map(results, function(result) { | ||
var tagResults = _.zip(result.result.tag.timestamps, result.result.tag.classes, result.result.tag.concept_ids, result.result.tag.probs) | ||
var timestamps = _.map(tagResults, function(tag) { | ||
var timeStampResults = _.zip(tag[1], tag[2], tag[3]) | ||
return { | ||
timestamp: tag[0], | ||
tags: _.map(timeStampResults, function(tsResult) { | ||
return { | ||
class: tsResult[0], | ||
conceptId: tsResult[1], | ||
probability: tsResult[2] | ||
} | ||
}) | ||
} | ||
}) | ||
var ret = { | ||
docId: result.docid, | ||
docIdStr: result.docid_str, | ||
timestamps: timestamps | ||
} | ||
return ret | ||
}) | ||
if (results.length < 2) { | ||
results = _.first(results) | ||
} | ||
return results | ||
} | ||
Clarifai.prototype.getAccessToken = function(cb) { | ||
var _this = this | ||
var data = { | ||
grant_type: 'client_credentials', | ||
client_id: this.id, | ||
client_secret: this.secret | ||
} | ||
_request('post', 'token', data, null, this, function(err, body) { | ||
_this.accessToken = body.access_token | ||
_this.expiresIn = body.expires_in | ||
_this.scope = body.scope | ||
_this.tokenType = body.token_type | ||
cb(err, _this.accessToken) | ||
}) | ||
} | ||
Clarifai.prototype.addTags = function(docIds, tags, cb) { | ||
var data = '' | ||
data +='docids=' + _array(docIds).join(',') | ||
data +='&add_tags=' + _array(tags).join(',') | ||
_request('post', 'feedback', data, this.options, this, cb) | ||
} | ||
Clarifai.prototype.removeTags = function(docIds, tags, cb) { | ||
var data = '' | ||
data +='docids=' + _array(docIds).join(',') | ||
data +='&remove_tags=' + _array(tags).join(',') | ||
_request('post', 'feedback', data, this.options, this, cb) | ||
} | ||
Clarifai.prototype.addSimilarDocIds = function(docIds, otherIds, cb) { | ||
var data = '' | ||
data +='docids=' + _array(docIds).join(',') | ||
data +='&similar_docids=' + _array(otherIds).join(',') | ||
_request('post', 'feedback', data, this.options, this, cb) | ||
} | ||
Clarifai.prototype.addDissimilarDocIds = function(docIds, otherIds, cb) { | ||
var data = '' | ||
data +='docids=' + _array(docIds).join(',') | ||
data +='&dissimilar_docids=' + _array(otherIds).join(',') | ||
_request('post', 'feedback', data, this.options, this, cb) | ||
} | ||
Clarifai.prototype.associateSearchTerms = function(docIds, terms, cb) { | ||
var data = '' | ||
data +='docids=' + _array(docIds).join(',') | ||
data +='&search_click=' + _array(terms).join(',') | ||
_request('post', 'feedback', data, this.options, this, cb) | ||
} | ||
Clarifai.prototype.getAPIDetails = function(cb) { | ||
_request('get', 'info', null, this.options, this, function(err, body) { | ||
cb(err, body.results) | ||
}) | ||
} | ||
Clarifai.prototype.tagFromUrls = function(type, urls, cb, lang) { | ||
var data = _encodeTagUrls(urls, lang) | ||
_request('post', 'tag', data, this.options, this, function(err, body) { | ||
if(err) { | ||
return cb(err) | ||
} else if (type === 'image') { | ||
return cb(err, formatImageResults(body)) | ||
} else{ | ||
return cb(err, formatVideoResults(body)) | ||
} | ||
}) | ||
} | ||
Clarifai.prototype.tagFromBuffers = function(type, buffers, cb, lang) { | ||
var data = _buildMultipart(buffers, lang) | ||
var options = _.cloneDeep(this.options || {}) | ||
options.headers = options.headers || {} | ||
options.headers['Content-Type'] = 'multipart/form-data; boundary=' + _boundary | ||
options.headers['Content-Length'] = data.length | ||
_request('post', 'tag', data, options, this, function(err, body) { | ||
if (err) { | ||
return cb(err) | ||
} else if (type === 'image') { | ||
return cb(err, formatImageResults(body)) | ||
} else { | ||
return cb(err, formatVideoResults(body)) | ||
} | ||
}) | ||
} | ||
function Clarifai (opts) { | ||
opts = opts || { | ||
id: process.env.CLARIFAI_ID, | ||
secret: process.env.CLARIFAI_SECRET | ||
} | ||
this.id = opts.id | ||
this.secret = opts.secret | ||
this.options = {} | ||
} | ||
module.exports = Clarifai | ||
}; |
{ | ||
"name": "clarifai", | ||
"version": "0.4.0", | ||
"description": "A Node integration library for clarifai", | ||
"version": "1.2.0", | ||
"description": "Official Clarifai Javascript SDK", | ||
"main": "index.js", | ||
"engines": { | ||
"node": "5.6.0" | ||
"repository": "https://github.com/Clarifai/javascript-sdk", | ||
"author": "Clarifai Inc.", | ||
"license": "Apache-2.0", | ||
"dependencies": { | ||
"axios": "0.9.1", | ||
"es6-promise": "3.1.2" | ||
}, | ||
"scripts": { | ||
"test": "./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/.bin/codacy-coverage && rm -rf ./coverage", | ||
"2npm": "publish" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://ctartist621@github.com/ctartist621/clarifai.git" | ||
}, | ||
"keywords": [ | ||
"clarifai", | ||
"AI", | ||
"artificial", | ||
"intelligence", | ||
"video", | ||
"image", | ||
"tagging" | ||
], | ||
"author": "David B Mittelman", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/ctartist621/clarifai/issues" | ||
}, | ||
"homepage": "https://github.com/ctartist621/clarifai#readme", | ||
"devDependencies": { | ||
"chai": "3.5.0", | ||
"codacy-coverage": "1.1.3", | ||
"istanbul": "0.4.2", | ||
"mocha": "2.4.5", | ||
"mocha-lcov-reporter": "1.2.0", | ||
"publish": "0.5.0" | ||
}, | ||
"dependencies": { | ||
"lodash": "4.5.1", | ||
"needle": "1.0.0" | ||
}, | ||
"config": { | ||
"blanket": { | ||
"pattern": [ | ||
"" | ||
], | ||
"data-cover-never": [ | ||
"node_modules", | ||
"tests" | ||
] | ||
} | ||
"del": "2.0.2", | ||
"envify": "3.4.0", | ||
"git-branch": "0.3.0", | ||
"gulp": "3.9.0", | ||
"gulp-awspublish": "3.0.1", | ||
"gulp-browserify": "0.5.1", | ||
"gulp-concat": "2.6.0", | ||
"gulp-data": "1.2.1", | ||
"gulp-eslint": "2.0.0", | ||
"gulp-htmlmin": "1.2.0", | ||
"gulp-if": "2.0.0", | ||
"gulp-imagemin": "2.3.0", | ||
"gulp-insert": "0.5.0", | ||
"gulp-jasmine": "^2.2.1", | ||
"gulp-newer": "0.5.1", | ||
"gulp-notify": "2.2.0", | ||
"gulp-rename": "1.2.2", | ||
"gulp-replace-task": "0.11.0", | ||
"gulp-uglify": "1.4.1", | ||
"gulp-util": "3.0.6", | ||
"gulp-webserver": "0.9.1", | ||
"gulp-zip": "^3.2.0", | ||
"require-dir": "0.3.0", | ||
"serve-static": "1.10.0" | ||
} | ||
} |
507
README.md
@@ -1,341 +0,258 @@ | ||
[![Circle CI](https://circleci.com/gh/ctartist621/clarifai/tree/master.svg?style=svg&circle-token=e15ad7ff3e856e1b86fb002868fb4c9e98d4e22e)](https://circleci.com/gh/ctartist621/clarifai/tree/master) [![npm version](https://badge.fury.io/js/clarifai.svg)](https://badge.fury.io/js/clarifai) [![Codacy Badge](https://api.codacy.com/project/badge/grade/fd34502ca14c4c0ba556e90a81d77991)](https://www.codacy.com/app/ctartist621/clarifai) [![Codacy Badge](https://api.codacy.com/project/badge/coverage/fd34502ca14c4c0ba556e90a81d77991)](https://www.codacy.com/app/ctartist621/clarifai) [![Dependency Status](https://david-dm.org/ctartist621/clarifai.svg)](https://david-dm.org/ctartist621/clarifai) [![devDependency Status](https://david-dm.org/ctartist621/clarifai/dev-status.svg)](https://david-dm.org/ctartist621/clarifai#info=devDependencies) | ||
# Clarifai JavaScript Client | ||
# clarifai | ||
A Node integration library for [Clarifai](http://clarifai.com/), a very cool content tagging api. | ||
The official JavaScript client for interacting with the [Clarifai API](https://developer.clarifai.com). | ||
## Basic Use | ||
## Installation | ||
To start, install the SDK via NPM: `npm install clarifai` and initialize with your clientId and | ||
clientSecret: | ||
First, the all necessary | ||
``` | ||
npm install clarifai --save | ||
``` | ||
*This will work in node.js and browsers via [Browserify](http://browserify.org/)* | ||
To initialize the library, you can either pass it in a settings object with the Clarifai ID & Secret, | ||
```js | ||
var Clarifai = require('clarifai'); | ||
``` | ||
var Clarifai = require('clarifai') | ||
client = new Clarifai({ | ||
id: <clarifai id>, | ||
secret: <clarifai secret> | ||
}) | ||
``` | ||
Clarifai.initialize({ | ||
'clientId': '{clientId}', | ||
'clientSecret': '{clientSecret}' | ||
}); | ||
Or save them as environment variables, as the library will also look for them in these two variables: | ||
``` | ||
process.env.CLARIFAI_ID | ||
process.env.CLARIFAI_SECRET | ||
``` | ||
And initializing is simply | ||
``` | ||
client = new Clarifai() | ||
``` | ||
## Authentication | ||
Once initialized, the library will take care of renewing the access token as it expires. If you need to OAuth for an access token, you can simply call: | ||
You can also use the SDK by adding this script to your HTML: | ||
```js | ||
<script type="text/javascript" src="https://sdk.clarifai.com/js/clarifai-1.2.0.js"></script> | ||
<script> | ||
Clarifai.initialize({ | ||
'clientId': '{clientId}', | ||
'clientSecret': '{clientSecret}' | ||
}); | ||
</script> | ||
``` | ||
client.getAccessToken(function(err, accessToken) { | ||
// Callback code here | ||
}) | ||
``` | ||
## Tagging | ||
## Table of Contents | ||
### Image Tagging via URL | ||
``` | ||
client.tagFromUrls('image', url, function(err, results) { | ||
// Callback code here | ||
}, [language]) | ||
``` | ||
This function will take one image URL, or many image URLs as an array. The language parameter is optional, and will request tags from Clarifai in the appropriate language. | ||
#### Tag | ||
The callback returns the standard error/results. The results object returned has the following structure: | ||
``` | ||
{ | ||
docId: 15512461224882630000, | ||
docIdStr: '31fdb2316ff87fb5d747554ba5267313', | ||
tags: [ | ||
{ | ||
class: 'train', | ||
conceptId: 'ai_HLmqFqBf', | ||
probability: 0.9989112019538879 | ||
}, | ||
{ | ||
class: 'railway', | ||
conceptId: 'ai_fvlBqXZR', | ||
probability: 0.9975532293319702 | ||
}, | ||
{ | ||
class: 'transportation system', | ||
conceptId: 'ai_Xxjc3MhT', | ||
probability: 0.9959157705307007 | ||
}, | ||
{ | ||
class: 'station', | ||
conceptId: 'ai_6kTjGfF6', | ||
probability: 0.9925730228424072 | ||
}, | ||
{ | ||
class: 'train', | ||
conceptId: 'ai_RRXLczch', | ||
probability: 0.9925559759140015 | ||
}, | ||
{ | ||
class: 'travel', | ||
conceptId: 'ai_VRmbGVWh', | ||
probability: 0.9878921508789062 | ||
}, | ||
{ | ||
class: 'tube', | ||
conceptId: 'ai_SHNDcmJ3', | ||
probability: 0.9816359281539917 | ||
}, | ||
{ | ||
class: 'commuter', | ||
conceptId: 'ai_jlb9q33b', | ||
probability: 0.9712483286857605 | ||
}, | ||
{ | ||
class: 'railway', | ||
conceptId: 'ai_46lGZ4Gm', | ||
probability: 0.9690325260162354 | ||
}, | ||
{ | ||
class: 'traffic', | ||
conceptId: 'ai_tr0MBp64', | ||
probability: 0.9687051773071289 | ||
}, | ||
{ | ||
class: 'blur', | ||
conceptId: 'ai_l4WckcJN', | ||
probability: 0.9667078256607056 | ||
}, | ||
{ | ||
class: 'platform', | ||
conceptId: 'ai_2gkfMDsM', | ||
probability: 0.9624242782592773 | ||
}, | ||
{ | ||
class: 'urban', | ||
conceptId: 'ai_CpFBRWzD', | ||
probability: 0.960752010345459 | ||
}, | ||
{ | ||
class: 'no person', | ||
conceptId: 'ai_786Zr311', | ||
probability: 0.9586490392684937 | ||
}, | ||
{ | ||
class: 'business', | ||
conceptId: 'ai_6lhccv44', | ||
probability: 0.9572030305862427 | ||
}, | ||
{ | ||
class: 'track', | ||
conceptId: 'ai_971KsJkn', | ||
probability: 0.9494642019271851 | ||
}, | ||
{ | ||
class: 'city', | ||
conceptId: 'ai_WBQfVV0p', | ||
probability: 0.940894365310669 | ||
}, | ||
{ | ||
class: 'fast', | ||
conceptId: 'ai_dSCKh8xv', | ||
probability: 0.9399334192276001 | ||
}, | ||
{ | ||
class: 'road', | ||
conceptId: 'ai_TZ3C79C6', | ||
probability: 0.9312160611152649 | ||
}, | ||
{ | ||
class: 'terminal', | ||
conceptId: 'ai_VSVscs9k', | ||
probability: 0.9230834245681763 | ||
} | ||
] | ||
} | ||
``` | ||
If one image was passed in, the `results` object will be the single object representing the results for that image. If more than one was passed in, it will be an array of `results` objects. | ||
* [Get tags for an image via URL](#get-tags-for-an-image-via-url) | ||
* [Get tags for an image via bytes](#get-tags-for-an-image-via-image-bytes) | ||
* [Get tags for multiple images via url](#get-tags-for-multiple-images-via-url) | ||
* [Get tags for an image via url passing in a model](#get-tags-for-an-image-via-url-passing-in-a-model) | ||
* [Get tags for an image via url passing in a language](#get-tags-for-an-image-via-url-passing-in-a-language) | ||
* [Get tags for an image via url and set a localId](#get-tags-for-an-image-via-url-and-set-a-localid) | ||
* [Get tags for an image via url and restrict the tags returned](#get-tags-for-an-image-via-url-and-restrict-the-tags-returned) | ||
### Video Tagging via URL | ||
``` | ||
client.tagFromUrls('video', url, function(err, results) { | ||
// Callback code here | ||
}, [language]) | ||
``` | ||
This function will take one video URL, or many video URLs as an array. The language parameter is optional, and will request tags from Clarifai in the appropriate language. | ||
#### Info | ||
The callback returns the standard error/results. The `results` object returned has the following structure: | ||
``` | ||
{ | ||
"docId": 13756317490038290000, | ||
"docIdStr": "9b1c7eabd9ac0932bee841df8339b916", | ||
"timestamps": [ | ||
{ | ||
"timestamp": 0, | ||
"tags": [ | ||
{ | ||
"class": "snow", | ||
"conceptId": "ai_l09WQRHT", | ||
"probability": 0.9933538436889648 | ||
}, | ||
{ | ||
"class": "ice", | ||
"conceptId": "ai_jGkHfX9T", | ||
"probability": 0.9898617267608643 | ||
} | ||
... | ||
{ | ||
"class": "sea", | ||
"conceptId": "ai_7bRKqWjp", | ||
"probability": 0.8838980793952942 | ||
} | ||
] | ||
}, | ||
{ | ||
"timestamp": 1, | ||
"tags": [ | ||
{ | ||
"class": "water", | ||
"conceptId": "ai_BlL0wSQh", | ||
"probability": 0.9734385013580322 | ||
}, | ||
{ | ||
"class": "snow", | ||
"conceptId": "ai_l09WQRHT", | ||
"probability": 0.9672313332557678 | ||
} | ||
... | ||
{ | ||
"class": "fair weather", | ||
"conceptId": "ai_41s912fX", | ||
"probability": 0.7390187978744507 | ||
} | ||
] | ||
}, | ||
{ | ||
"timestamp": 2, | ||
"tags": [ | ||
{ | ||
"class": "frosty", | ||
"conceptId": "ai_LMNcLLVR", | ||
"probability": 0.9763497114181519 | ||
}, | ||
{ | ||
"class": "water", | ||
"conceptId": "ai_BlL0wSQh", | ||
"probability": 0.9734385013580322 | ||
} | ||
... | ||
{ | ||
"class": "recreation", | ||
"conceptId": "ai_8Qw6PFLZ", | ||
"probability": 0.7853384017944336 | ||
} | ||
] | ||
} | ||
... | ||
] | ||
} | ||
``` | ||
Each classification is taken at 1 second keyframes by Clarifai, so each keyframe has a set of tags associated with it. So the document's `results` object will have a timestamps array, and each timestamp will have an array of tags associated with that timestamp. | ||
* [Get API info](#get-api-info) | ||
If one video was passed in, the `results` object will be the single object representing the results for that image. If more than one was passed in, it will be an array of `results` objects. | ||
#### Languages | ||
* [Get supported languages](#get-supported-languages) | ||
### Image and Video Tagging from Buffers | ||
``` | ||
client.tagFromBuffers('image', buffer, function(err, results) { | ||
// Callback code here | ||
}, [language]) | ||
``` | ||
This function will take one Buffer containing image or video data, or many Buffers as an array. The language parameter is optional, and will request tags from clarifai in the appropriate language. | ||
#### Color | ||
The response format is the same as for image or video URLs, as described in the previous sections. | ||
* [Get colors for an image via url](#get-colors-for-an-image-via-url) | ||
#### Usage | ||
* [Get API usage](#get-api-usage) | ||
## Feedback | ||
For all the feedback functions, any input parameters can be a single string, or an array of strings. | ||
#### Feedback | ||
Any positive response will look like: | ||
* [Send feedback to the API](#send-feedback-to-the-api) | ||
#### Token | ||
* [Get a token](#get-a-token) | ||
* [Set a token](#set-a-token) | ||
* [Delete a token](#delete-a-token) | ||
#### Promises and Callbacks | ||
* [Instructions](#promises-and-callbacks) | ||
## Examples | ||
### Tag | ||
#### Get tags for an image via url | ||
```js | ||
Clarifai.getTagsByUrl('https://samples.clarifai.com/wedding.jpg').then( | ||
handleResponse, | ||
handleError | ||
); | ||
``` | ||
{ | ||
"status_code": "OK", | ||
"status_msg": "Feedback sucessfully recorded." | ||
} | ||
#### Get tags for multiple images via url | ||
```js | ||
Clarifai.getTagsByUrl([ | ||
'https://samples.clarifai.com/wedding.jpg', | ||
'https://samples.clarifai.com/cookies.jpeg' | ||
]).then( | ||
handleResponse, | ||
handleError | ||
); | ||
``` | ||
### Add tags or give positive feedback for tags to a docid | ||
#### Get tags for an image via image bytes | ||
```js | ||
Clarifai.getTagsByImageBytes('R0lGODlhZAHIAPcAAKeno6Oinc3Do6iVeMe7o1ZEM...').then( | ||
handleResponse, | ||
handleError | ||
); | ||
``` | ||
var docIds = ['78c742b9dee940c8cf2a06f860025141'] | ||
var tags = ['car','dashboard','driving'] | ||
client.addTags(docIds, tags, function(err, resp) { | ||
// Callback code here | ||
}) | ||
#### Get tags for an image via url passing in a model | ||
```js | ||
Clarifai.getTagsByUrl('https://samples.clarifai.com/wedding.jpg', { | ||
'model': 'nsfw-v0.1' | ||
}).then( | ||
handleResponse, | ||
handleError | ||
); | ||
``` | ||
### Remove tags or give negative feedback for tags to a docid | ||
#### Get tags for an image via url passing in a language | ||
```js | ||
Clarifai.getTagsByUrl('https://samples.clarifai.com/wedding.jpg', { | ||
'language': 'es' | ||
}).then( | ||
handleResponse, | ||
handleError | ||
); | ||
``` | ||
var docIds = ['78c742b9dee940c8cf2a06f860025141'] | ||
var tags = ['sky','clean','red'] | ||
client.removeTags(docIds, tags, function(err, resp) { | ||
// Callback code here | ||
}) | ||
#### Get tags for an image via url and set a localId | ||
```js | ||
Clarifai.getTagsByUrl('https://samples.clarifai.com/wedding.jpg', { | ||
'localId': 'myLocalId' | ||
}).then( | ||
handleResponse, | ||
handleError | ||
); | ||
``` | ||
### Add similar docids for a given docid | ||
#### Get tags for an image via url and restrict the tags returned | ||
```js | ||
Clarifai.getTagsByUrl( | ||
'https://samples.clarifai.com/wedding.jpg', | ||
{ | ||
'selectClasses': ['people', 'dress', 'wedding'] | ||
} | ||
).then( | ||
handleResponse, | ||
handleError | ||
); | ||
``` | ||
var docIds = ['78c742b9dee940c8cf2a06f860025141'] | ||
var similarIds = ['fc957ec10abcc0f4507475827626200a'] | ||
client.addSimilarDocIds(docIds, similarIds, function(err, resp) { | ||
// Callback code here | ||
}) | ||
### Info | ||
#### Get API info | ||
```js | ||
Clarifai.getInfo().then( | ||
handleResponse, | ||
handleError | ||
); | ||
``` | ||
### Add dissimilar docids for a given docid | ||
### Languages | ||
#### Get supported languages | ||
```js | ||
Clarifai.getLanguages().then( | ||
handleResponse, | ||
handleError | ||
); | ||
``` | ||
var docIds = ['78c742b9dee940c8cf2a06f860025141'] | ||
var dissimilarIds = ['acd57ec10abcc0f4507475827626785f'] | ||
client.addDissimilarDocIds(docIds, dissimilarIds, function(err, resp) { | ||
// Callback code here | ||
}) | ||
### Color | ||
#### Get colors for an image via url | ||
```js | ||
Clarifai.getColorsByUrl('https://samples.clarifai.com/wedding.jpg').then( | ||
handleResponse, | ||
handleError | ||
); | ||
``` | ||
### Associate search tags for which the input docids were clicked | ||
#### Get colors for an image via image bytes | ||
```js | ||
Clarifai.getColorsByImageBytes('R0lGODlhZAHIAPcAAKeno6Oinc3Do6iVeMe7o1ZEM...').then( | ||
handleResponse, | ||
handleError | ||
); | ||
``` | ||
var docIds = ['78c742b9dee940c8cf2a06f860025141'] | ||
var terms = ['cat'] | ||
client.associateSearchTerms(docIds, terms, function(err, resp) { | ||
// Callback code here | ||
}) | ||
### Usage | ||
#### Get API usage | ||
```js | ||
Clarifai.getUsage().then( | ||
handleResponse, | ||
handleError | ||
); | ||
``` | ||
## API Info | ||
Retrieves information about the API. | ||
### Feedback | ||
#### Send feedback to the API | ||
```js | ||
Clarifai.createFeedback('https://samples.clarifai.com/wedding.jpg', { | ||
'addTags': ['family', 'friends',], | ||
'removeTags': ['military', 'protest'], | ||
}).then( | ||
handleResponse, | ||
handleError | ||
); | ||
``` | ||
client.getAPIDetails(function(err, resp) { | ||
// Callback code here | ||
}) | ||
### Token | ||
#### Get a token | ||
**Note:** You should not have to call this directly in most cases. Any method that needs a token will call | ||
it for you. | ||
```js | ||
Clarifai.getToken().then( | ||
function(response) { | ||
console.log(response); | ||
}, | ||
function(err){ | ||
console.log(err); | ||
} | ||
); | ||
``` | ||
Response will look like: | ||
#### Set a token | ||
```js | ||
var tokenSetBoolean = Clarifai.setToken('some-token-string'); | ||
``` | ||
{ | ||
max_image_size: 100000, | ||
default_language: 'en', | ||
max_video_size: 100000, | ||
max_image_bytes: 10485760, | ||
min_image_size: 1, | ||
default_model: 'general-v1.3', | ||
max_video_bytes: 104857600, | ||
max_video_duration: 1800, | ||
max_batch_size: 128, | ||
max_video_batch_size: 1, | ||
min_video_size: 1, | ||
api_version: 0.1 | ||
} | ||
#### Delete a token | ||
```js | ||
Clarifai.deleteToken(); | ||
``` | ||
### Promises and Callbacks | ||
All methods return promises. If you'd rather user callbacks, just pass in a callback function as the last | ||
param to any method. If there are multiple params and some are optional, you'll need to pass in `null` for | ||
those. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
NPM Shrinkwrap
Supply chain riskPackage contains a shrinkwrap file. This may allow the package to bypass normal install procedures.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
22
0
62976
24
1196
2
259
11
2
+ Addedaxios@0.9.1
+ Addedes6-promise@3.1.2
+ Addedaxios@0.9.1(transitive)
+ Addedes6-promise@3.1.2(transitive)
+ Addedfollow-redirects@0.0.7(transitive)
+ Addedstream-consume@0.1.1(transitive)
- Removedlodash@4.5.1
- Removedneedle@1.0.0
- Removediconv-lite@0.4.24(transitive)
- Removedlodash@4.5.1(transitive)
- Removedneedle@1.0.0(transitive)
- Removedsafer-buffer@2.1.2(transitive)