Storage Backend for Human Computation application.
This application allow to Store, Retrieve and Update data related to Human Computation tasks using REST APIs.
Developed By Carlo Bernaschina (GitHub - B3rn475)
www.bernaschina.com
Copyright (c) 2014 Politecnico di Milano
www.polimi.it
Distributed under the MIT License
In order to allow future modifications it has been chosen to force the remote Host to choose the output format of the APIs.
This is done using the Accept HTTP Header.
Accepted Formats:
- application/json
If the header is not set as a common Web Application is goes for the default text/html format, that is currently non implemented.
If you receive a 501 : not implemented error first check the Accept Header of your request.
The main idea is to use the right HTTP Method for the operation.
- GET to obtain data
- POST to add new data or to do one time operations
- PUT to update elements
- DELETE to remove items
Image
fields:
- id: { type: Number, min: 0, index: { unique: true }}
- width: { type: Number, min: 1}
- height: { type: Number, min: 1}
- mediaLocator: {type: String} // virtual
- pose: []
- location: {type: String, enum: ["head", "torso", "left_arm", "right_arm", "legs", "feet"]},
- x0 : { type: Number, min: 0, max: width - 1},
- y0 : { type: Number, min: 0, max: height - 1},
- x1 : { type: Number, min: 0, max: width - 1},
- y1 : { type: Number, min: 0, max: height - 1}
Collection
fields:
- id: { type: Number, min: 0, index: { unique: true }}
- name: {type: String, validate: /[a-zA-Z ]+$/}
- images : [ Image ]
Tag
fields:
- id: { type: Number, min: 0, index: { unique: true }, select: false}
- name: {type: String, validate: /[a-zA-Z ]+$/}
- aliases: []
- language: {type: String, validate: /[a-z]{2}-[A-Z]{2}$/}
- name: {type: String, validate: /[a-zA-Z ]+$/}
User
fields:
- id: { type: Number, min: 0, index: { unique: true }}
- app_id: { type: Number, min: 0}
- app_user_id: { type: String}
- quality: { type: Number}
- statistics : { sessions: {type: Number} actions: {type: Number} }
Mask
fields:
- id: { type: Number, min: 0, index: { unique: true }},
- image: Image
- tag: Tag
- quality: { type: Number}
- segmentations: { type: Number, min: 1}
- updated_at: {type: Date}
- mediaLocator: {type: String} // virtual
Session
fields:
- id: { type: Number, min: 0, index: { unique: true }}
- created_at: {type: Date}
- completed_at: {type: Date}
Action
fields:
- id: { type: Number, min: 0, index: { unique: true }},
- session: Session
- image: Image
- tag: Tag
- user: User
- type: {type: String, enum: ["tagging", "segmentation", "upload"]},
- segmentation:
- quality: { type: Number}
- points: []
- x: { type: Number, min: 0}
- y: { type: Number, min: 0}
- end: { type: Boolean: default: undefined}
- history: []
- size: {type: Number, min: 1}
- color: {type: String, validate: /(rgb(([0-1][0-9]{2}|2[0-4][0-9]|25[0-5]|[0-9]{2}|[0-9]),[ ]([0-1][0-9]{2}|2[0-4][0-9]|25[0-5]|[0-9]{2}|[0-9]),[ ]([0-1][0-9]{2}|2[0-4][0-9]|25[0-5]|[0-9]{2}|[0-9])))|(rgba(([0-1][0-9]{2}|2[0-4][0-9]|25[0-5]|[0-9]{2}|[0-9]),[ ]([0-1][0-9]{2}|2[0-4][0-9]|25[0-5]|[0-9]{2}|[0-9]),[ ]([0-1][0-9]{2}|2[0-4][0-9]|25[0-5]|[0-9]{2}|[0-9]),[ ]*(1|0|1.0|0.[0-9]+)))/}
- time : {type:Number, min 0}
- points: []
- x: { type: Number}
- y: { type: Number}
- started_at: {type: Date},
- completed_at: {type: Date},
- validity: {type: Boolean, default: true}
for tagging:
tag can be present or not. If it is present the action is completed otherwise skipped
segmentation is not present
for segmentation:
tag is always present.
segmentation can be present or not. If it is present the action is completed otherwise skipped
Task
fields:
- id: { type: Number, min: 0, index: { unique: true }}
- image: [ Image ]
- users : [ User ]
- created_at: {type: Date}
- completed_at: {type: Date}
Microtask
fields:
- id: { type: Number, min: 0, index: { unique: true }}
- type: {type: String, enum: ["tagging", "segmentation"]}
- task: Task
- action: Action
- order: {type: Number, min: 0}
- created_at: {type: Date}
- completed_at: {type: Date}
JSON
If there is an error during the process, due to a Bad Route, a Missing or Wrong Parameter or to an Internal Server Error an error message will be returned.
Format:
{
"status": "KO",
"errors": [{"location": "url|body|query|status|internal",
"name": "parameter that has generate the error",
"message": "description of the error"
}]
}
JSON
If there are not errors during the operation the following object will be sent:
{
"status": "OK",
... //Other data related to the api
}
Format:
METHOD : PATH description:
- location : name : optional|mandatory : description
- ...
The following routes are corrently available:
GET : /
get the status of the server
Image
GET : /image
returns the list of the images
- query : count : optional : max number of items to returns (max: 100)
- query : max_id : optional : upper bound for the id to returns (included)
- query : since_id : optional : lower bound for the id to returns (not included)
- query : min_segmentations : optional : lower bound for the number of segmentations (included)
- query : max_segmentations : optional : upper bound for the number of segmentations (included)
Example result:
{
"status" : "OK",
"search_metadata" : {
"count" : 100,
"refresh_url" : "?since_id=2&count=100"
},
"images" : [
{
"width" : 600,
"height" : 921,
"pose" : [],
"id" : 2,
"mediaLocator" : "/storage/image/2.jpg"
},
{
"width" : 600,
"height" : 921,
"pose" : [],
"id" : 1,
"mediaLocator" : "/storage/image/1.jpg"
},
{
"width" : 600,
"height" : 921,
"pose": [],
"id": 0,
"mediaLocator": "/storage/image/0.jpg"
}
]
}
POST : /image
adds a new image
- body : payload : optional : the content of the image encoded in Base64 (jpeg or png format)
- body : url : optional : the url of the image (jpeg or png format)
- body : pose : optional : pose of the image (see definition)
at least one between payload or url must be present.
Example result:
{
"status" : "OK",
"id" : 0
}
GET : /image/count
returns the number of images
Example result:
{
"status" : "OK",
"count" : 123
}
GET : /image/:imageId
returns an image
Example result:
{
"status" : "OK",
"image" : {
"width" : 600,
"height" : 921,
"pose" : [],
"id" : 0,
"mediaLocator" : "/storage/image/0.jpg"
}
}
PUT : /image/:imageId
updates the image information
- body : pose : mandatory : pose of the image (see definition)
GET : /image/:imageId/tag
returns the list of tags related to this image
Example result:
{
"status" : "OK",
"search_metadata" : {
"count" : 100,
"refresh_url" : "?since_id=0&count=100"
},
"tags" : [
{
"aliases" : [
{
"language" : "en-US",
"name" : "hat"
},
{
"language" : "it-IT",
"name" : "cappello"
}
],
"name" : "hat",
"id" : 0
}
]
}
Collection
GET : /collection
returns the list of collections
- query : count : optional : max number of items to returns (max: 100)
- query : max_id : optional : upper bound for the id to returns (included)
- query : since_id : optional : lower bound for the id to returns (not included)
POST : /collection
adds a new collection
- body : name : mandatory : name of the collection
GET :/collection/count
returns the number of collections
GET : /collection/:collectionId
returns a collection
GET : /collection/:collectionId/task
returns the list of task related to images in the collection
POST : /collection/:collectionId/image adds an image to the collection
- body : image : mandatory : the image to add to the collection
DELETE : /collection/:collectionId/image
remove an image from the collection
- body : image : mandatory : the image to remove from the collection
DELETE : /collection/:collectionId/image/:imageId remove an image from the collection (same as the previous one, but with the id explicit in the url)
User
GET : /user
returns the list of users
- query : count : optional : max number of items to returns (max: 100)
- query : max_id : optional : upper bound for the id to returns (included)
- query : since_id : optional : lower bound for the id to returns (not included)
- query : app_id : optional : returns only users from a particular application
- query : populate : optional : shows the user statistics
POST : /user
adds a new user (if it is already there returns the id)
- body : app_id : mandatory : id of the application
- body : app_user_id : mandatory : id of the user of the application
GET : /user/count returns the number of users
- query : app_id : optional : counts only users from a particular application
GET : /user/:userId
returns a user
- query : populate : optional : shows the user statistics
PUT : /user/:userId updates the user information
- body : quality : mandatory : quality of the user
Tag
GET : /tag
returns the list of tags
- query : count : optional : max number of items to returns (max: 100)
- query : max_id : optional : upper bound for the id to returns (included)
- query : since_id : optional : lower bound for the id to returns (not included)
POST : /tag
adds a new tag
- body : name : mandatory : name of the tag
GET : /tag/count
returns the number of tags
GET : /tag/:tagId
returns a tag
POST : /tag/:tagId/alias
adds a new alias to the tag
- body : language : mandatory : language of the alias (ex: en-US)
- body : name : mandatory : name of the alias
DELETE : /tag/:tagId/alias remove an alias from the tag
- body : language : mandatory : language of the alias (ex: end-US)
DELETE : /tag/:tagId/alias/:language remove an alias from the tag (same as the previous one, but with the language explicit in the url)
Mask
GET : /mask
returns the list of masks
- query : count : optional : max number of items to returns (max: 100)
- query : max_id : optional : upper bound for the id to returns (included)
- query : since_id : optional : lower bound for the id to returns (not included)
- query : image : optional : returns only mask related to that image
- query : tag : optional : returns only mask related to that tag
Example result:
{
"status" : "OK",
"search_metadata" : {
"count" : 100,
"refresh_url" : "?since_id=0&count=100"
},
"masks": [
{
"image" : 0,
"tag" : 0,
"segmentations" : 3,
"quality" : 0.3,
"mediaLocator" : "/storage/mask/0.png",
"id" : 0
}
]
}
POST : /mask adds a new mask
- body : image : mandatory : the image related to the mask
- body : tag : mandatory : the tag related to the mask
- body : payload : mandatory : the content of the mask (png format)
- body : segmentations : mandatory : the number of segmentations that has generated the mask
- body : quality : mandatory : the quality of the mask
GET : /mask/count
returns the number of mask
Example result:
{
"status" : "OK",
"count" : 123
}
- query : image : optional : counts only mask related to that image
- query : tag : optional : counts only mask related to that tag
GET : /mask/:maskId
returns a mask
Example result:
{
"status" : "OK",
"mask": {
"image" : 0,
"tag" : 0,
"segmentations" : 3,
"quality" : 0.3,
"mediaLocator" : "/storage/mask/0.png",
"id" : 0
}
}
PUT : /mask/:maskId updates a mask
- body : payload : mandatory : the content of the mask (png format)
- body : segmentations : mandatory : the number of segmentations that has generated the mask
- body : quality : mandatory : the quality of the mask
Task
GET : /task
returns the list of tasks
- query : count : optional : max number of items to returns (max: 100)
- query : max_id : optional : upper bound for the id to returns (included)
- query : since_id : optional : lower bound for the id to returns (not included)
- query : image : optional : returns only tasks related to that image (cannot be used with collection)
- query : collection : optional : returns only tasks related to images in that collection (cannot be used with image)
- query : completed : optional : returns only open or completed tasks
POST : /task adds a new task
- body : image : mandatory : image related to the task
GET : /task/count
returns the number of tasks
- query : image : optional : counts only tasks related to that image (cannot be used with collection)
- query : collection : optional : counts only tasks related to images in that collection (cannot be used with image)
- query : completed : optional : counts only open or completed tasks
GET : /task/:taskId
returns a task
POST : /task/:taskId
complete a task (and all the related microtasks)
POST : /task/:taskId/user adds a new users related to the task
- body : user : mandatory : the user to add
GET : /task/:taskId/microtask
returns the list of microtask related to this task (same as /microtask=:taskId)
- query : count : optional : max number of items to returns (max: 100)
- query : max_id : optional : upper bound for the id to returns (included)
- query : since_id : optional : lower bound for the id to returns (not included)
POST : /task/:taskId/microtask
adds a new microtask (the same as /microtask, but with the task id explicit in the url)
- body : type : mandatory : the type of the microtask
- body : order : mandatory : the order of the microtask
Session
GET : /session
returns the list of sessions
- query : count : optional : max number of items to returns (max: 100)
- query : max_id : optional : upper bound for the id to returns (included)
- query : since_id : optional : lower bound for the id to returns (not included)
- query : completed : optional : returns only open or completed sessions
POST : /session adds a new session
- body : created_at : optional : creation date (default now)
*GET : /session/count returns the number of sessions
- query : completed : optional : counts only open or completed sessions
GET : /session/:sessionId
returns a session
POST : /session/:sessionId
complete a session
- body : completed_at : optional : completion date (default now)
GET : /session/:sessionId/action
returns the actions related to this session (same as /action?session=:sessionId)
- query : count : optional : max number of items to returns (max: 100)
- query : max_id : optional : upper bound for the id to returns (included)
- query : since_id : optional : lower bound for the id to returns (not included)
- query : type : optional : returns only the action of that type
- query : image : optional : returns only the action related to that image
- query : tag : optional : returns only the action related to that tag
- query : completed : optional : returns only the completed or not completed actions
- query : validity : optional : returns only the valid or not valid actions
POST : /session/:sessionId/action adds a new action to the session (the same as /action, but with the session id explicit in the url).
- body : type : mandatory : the type of the action
- body : user : mandatory : the user related to the action
- body : tag : optional (for tagging) | mandatory (for segmentation) : the tag of the action
- body : points : optional (only for segmentation) : the points of the segmentation
- body : history : optional (only for segmentation) : the points of the segmentation
If it is a tagging action the tag is optional. If it is present the action is completed correctly otherwise it is still open.
If it is a segmentation action the tag is mandatory.
If it is a segmentation action the points and the history are optional. If they are present the action is completed correctly otherwise it is skipped.
Action
GET : /action
returns the list of actions
- query : count : optional : max number of items to returns (max: 100)
- query : max_id : optional : upper bound for the id to returns (included)
- query : since_id : optional : lower bound for the id to returns (not included)
- query : type : optional : returns only the action of that type
- query : image : optional : returns only the action related to that image
- query : tag : optional : returns only the action related to that tag
- query : completed : optional : returns only the completed or not completed actions
- query : validity : optional : returns only the valid or not valid actions
- query : populate : optional : returns even the segmentations points
POST : /action
adds a new action
- body : session : mandatory : session of the action
- body : type : mandatory : the type of the action
- body : user : mandatory : the user related to the action
- body : tag : optional (for tagging) | mandatory (for segmentation) : the tag of the action
- body : points : optional (only for segmentation) : the points of the segmentation
- body : history : optional (only for segmentation) : the points of the segmentation
If it is a tagging action the tag is optional. If it is present the action is completed correctly otherwise it is skipped.
If it is a segmentation action the tag is mandatory.
If it is a segmentation action the points and the history are optional. If they are present the action is completed correctly otherwise it is skipped.
GET : /action/count
returns the number of actions
- query : type : optional : counts only the action of that type
- query : image : optional : counts only the action related to that image
- query : tag : optional : counts only the action related to that tag
- query : completed : optional : counts only the completed or not completed actions
- query : validity : optional : counts only the valid or not valid actions
GET : /action/:actionId
returns an action
POST : /action/:actionId
completes the action
- body : tag : optional (only for tagging) : the tag of the action
- body : points : optional (only for segmentation) : the points of the segmentation
- body : history : optional (only for segmentation) : the history of the segmentation
If it is a tagging action and the tag is not present the action is skipped. If it is a segmentation action and the points are not present the action is skipped.
PUT : /action/:actionId
updates an action
- body : validity : optional : the new validity of the action
- body : quality : optional : the new quality of the action
Microtask
GET : /microtask
returns the list of microtasks
- query : count : optional : max number of items to returns (max: 100)
- query : max_id : optional : upper bound for the id to returns (included)
- query : since_id : optional : lower bound for the id to returns (not included)
- query : task : __optional : returns only the microtasks related to that task
- query : completed : __optional : returns only the open or completed tasks
POST : /microtask
adds a new microtask
- body : task : mandatory : the task of the microtask
- body : type : mandatory : the type of the microtask
- body : order : mandatory : the order of the microtask
GET : /microtask/count
returns the number of microtasks
- query : task : __optional : counts only the microtasks related to that task
- query : completed : __optional : counts only the open or completed tasks
GET : /microtask/:microtaskId
returns a microtask
POST : /microtask/:microtaskId
complete a microtask
- body : action : mandatory : the action that executes the task
Choose Routes
GET : /choose returns the list of the available objects to choose
GET : /choose/image returns the list of the available algorithms to choose images
GET : /choose/image/random choose a random image
- query : limit : optional : number of elements to return (default: 1, max: 100)
- query : collection : optional : collection from which take the images
GET : /choose/image/leastused choose the least used image
- query : limit : optional : number of elements to return (default: 1, max: 100)
- query : collection : optional : collection from which take the images
GET : /choose/imageandtag returns the list of the available algorithms to choose image and tag pairs
GET : /choose/imageandtag/random choose a random combination of image and tag that has already been tagged by a user
- query : limit : optional : number of elements to return (default: 1, max: 100)
- query : collection : optional : collection from which take the images
GET : /choose/imageandtag/leastused choose the least used combination of image and tag that has already been tagged by a user.
- query : limit : optional : number of elements to return (default: 1, max: 100)
- query : collection : optional : collection from which take the images
actions open from more than 1 hour are considered skipped from this route.
Statistics Routes
GET : /statistics returns statistics about the system