NAV
Python Javascript HTTP

Philosophy

Medium

A medium is a multimedia document (e.g. an audio file, an image or a video file).

attributes type
name String
url String
description free
history list
id_corpus id

Corpus

A corpus is simply a collection of media (e.g. all eight Harry Potter movies) – nothing more.

attributes type
name String
description free
history list
permissions dict

Fragment

A fragment is a part of a medium (e.g. a rectangular area of an image or a temporal segment of an audio file).

A fragment can be anything – be creative!

Annotation

An annotation is a fragment and its associated metadata (e.g. the name of the person whose face is covered by the rectangular area).

Once again, a metadata can be anything – be creative!

attributes type
fragment free
data free
history list
id_layer id
id_medium id

Layer

A layer is simply a collection of annotations sharing the same fragment type and metadata type.

attributes type
name String (lowercase)
description free
fragment_type free
data_type free
history list
permissions dict
id_corpus id

User

A user is a person with an account on the Camomile platform.

attributes type
username String (lowercase, unique)
description free
role “user” or “admin”

Group

A group is simply a set of users – how extraordinary!

attributes type
name String (lowercase, unique)
description free
users list

Queue

A queue is a list of items

attributes type
name String (lowercase, unique)
description free
list list of items

Server

The Camomile server is available on Github.

Installation

The recommended way to install and run the Camomile server is using Docker.

MongoDB

It relies on MongoDB for storing annotations.

$ export CMML_DB="/path/to/the/database"
$ docker run -d \
         -v $CMML_DB:/data/db \
         --name my_mongodb dockerfile/mongodb

Camomile REST API

Once the MongoDB container is up and running, the NodeJS Camomile server can use it as storage backend.

$ export CMML_MEDIA="/path/to/media/files"
$ docker run -d -P \
         -v $CMML_MEDIA:/media \
         -e ROOT_PASSWORD="R00t.p455w0rd" \
         --link my_mongodb:mongodb \
         --name camomile camomile/api
$ echo "Camomile server is now available at `docker port camomile 3000`"

Clients

Python

$ pip install camomile

The Python Camomile client is available on Github.

It can be installed easily using pip package manager.

Javascript

<script type="text/javascript" src="camomile.js"></script> 
<script type="text/javascript" src="fermata.js"></script> 

The Javascript Camomile client is available on Github.

To use it in your webapp, you need to include both camomile.js and fermata.js.

Reference

Foreword

CRUD REST API

CAMOMILE server follows the conventional REST API for CRUD (Create, Read, Update, Delete) data access. For a given resource (either corpus, medium, layer, annotation), the correspondance with HTTP commands and Python or Javascript interface is as follows.

Action HTTP command Python/Javascript interface
Create POST /resource .createResource(…)
Read GET /resource/:id_resource .getResource(:id_resource)
Update PUT /resource/:id_resource .updateResource(:id_resource,…)
Delete DELETE /resource/:id_resource .deleteResource(:id_resource)

Users and groups

Permissions

PUT /corpus/:id_corpus/user/:id_user HTTP/1.1

{"right":3}
client.setCorpusPermissions(id_corpus, client.ADMIN, user=id_user)
client.setCorpusPermissions(id_corpus, client.WRITE, user=id_user)
client.setCorpusPermissions(id_corpus, client.READ, group=id_group)
Camomile.setCorpusPermissionsForUser(
  id_corpus, id_user, Camomile.ADMIN, callback);
Camomile.setCorpusPermissionsForUser(
  id_corpus, id_user, Camomile.WRITE, callback);
Camomile.setCorpusPermissionsForGroup(
  id_corpus, id_group, Camomile.READ, callback);

The Camomile platform handles permissions: users may access only the resources for which they have enough permission.

Three levels of permissions are supported:

Annotations inherit permissions from the layer they belong to.

Media inherit permissions from the corpus they belong to.

Permissions needed for the CRUD actions are summarized in the table below

Corpus Permission needed
C 'admin’ role
R >= READ to the corpus
U/D ADMIN to the corpus and 'admin’ role
Medium Permission needed
C/U ADMIN to the corpus
R >= READ to the corpus
D ADMIN to the corpus
Layer Permission needed
C >= WRITE to the corpus
R >= READ to the layer
U/D ADMIN to the layer
Annotation Permission needed
C/U/D >= WRITE to the layer
R >= READ to the layer
User Permission needed
C/U/D 'admin’ role
R authenticated user
Group Permission needed
C/U 'admin’ role
R authenticated user
D 'root’ user
Queue Permission needed
C 'admin’ role
R WRITE to the queue (destructive access)
U/D ADMIN to the queue

Resource ID

corpora = client.getCorpora()
id_corpora = client.getCorpora(returns_id=true)
assert corpora[0]._id == id_corpora[0]
client.getCorpora(
  function(id_corpora) {
    do_something_with(id_corpora);
  },
  {returns_id: True}
);

Each resource is given a unique identifier (_id) by MongoDB upon creation.

The default behavior of most entry points is to return the complete resource, rather than just its _id.

However, methods of the Python and Javascript clients support the returns_id optional parameter. Setting it to true will return the resource MongoDB _id instead of the complete resource.

Filters

GET /corpus?name='my%20corpus' HTTP/1.1
corpora = client.getCorpora(name='my corpus')
assert corpora[0].name == 'my corpus'
client.getCorpora(
  function(corpora) {

  },
  {filter: {name: 'my corpus'}}
);

Most get{Resource} methods (e.g. getCorpora, getLayers, …) support filtering by resource attribute.

History

GET /corpus?history=on HTTP/1.1
corpus = client.getCorpus(id_corpus, history=True)
do_something_with(corpus.history)
client.getCorpus(
  id_corpus, 
  function (corpus) { 
    do_something_with(corpus.history); 
  },
  {history: True}
);

The API keeps track of all changes made to corpora, media, layers and annotations, in a dedicated history attribute.

The history is simply a list of updates that were applied to the resource. Each update has the following attributes:

However, to avoid sending what may become a very large amount of data with every request, the default behavior is to not send history.

If you really want to get the history, you need to ask for it explicitely to get it.

Authentication

login

POST /login

DATA PARAMETERS

Key Type Description
username String The user name (required)
password String The password (required)
POST /login HTTP/1.1

{'username': 'johndoe', 'password': 'secretpassword'}

from camomile import Camomile 
server = 'http://example.com'  
client = Camomile(server)
client.login(username, password)
var server = 'http://example.com';
Camomile.setURL(server);

JSON response upon success

{
 "success": "Authentication succeeded."
}

logout

POST /logout

POST /logout HTTP/1.1
client.logout()

JSON response upon success

{
 "success": "Logout succeeded."
}

get logged in user

GET /me

user = client.me()
id_user = client.me(returns_id=True)
GET /me HTTP/1.1

Sample JSON response

{
 "_id": "555299eff80f910100d741d1",
 "description": "",
 "role": "user",
 "username": "johndoe"
}

update password

PUT /me

client.update_password('new_password')
client.update_password("new_password", callback);
PUT /me HTTP/1.1

{
  "password": "new_password"
}

JSON response upon success

{
  "success": "Password successfully updated."
}

Users & Groups

create new user

POST /user

DATA PARAMETERS

Key Type Description
username String The user name (required, unique and without space, can’t be updated)
password String The password (required)
description free A description of the user
role String The user role (“admin” or “user”) (required)
POST /user HTTP/1.1

{'username': 'johndoe',
 'password': 'secretpassword',
 'description': 'annotator',
 'role': 'user'}

user = client.createUser('username', 'password', role='user',
                         description={'affiliation': 'LIMSI/CNRS', 
                                      'status': 'PhD student'})
client.createUser('username', 'password', 
                  {'affiliation': 'LIMSI/CNRS', 'status': 'PhD student'}
                  'user', callback);

Sample JSON response

{
 "_id": "558818da01e0ef01006e979b",
 "description": "annotator",
 "role": "user",
 "username": "johndoe"
}

delete one user

DELETE /user/:id_user

QUERY PARAMETERS

Parameter Type Description
id_user String The user identifier (required)
client.deleteUser(id_user)
DELETE /user/:id_user HTTP/1.1

JSON response upon success

{
 "success": "Successfully deleted."
}

get all users

GET /user

DATA PARAMETERS

Key Type Description
username String filter users by username (optional)
users = client.getUsers()
GET /user HTTP/1.1

Sample JSON response

[
 {
  "_id": "5552998df80f910100d741d0",
  "description": "",
  "role": "admin",
  "username": "root"
 },
 {
  "_id": "558818da01e0ef01006e979b",
  "description": "annotator",
  "role": "user",
  "username": "johndoe"
 }
]

get one user

GET /user/:id_user

QUERY PARAMETERS

Parameter Type Description
id_user String The user identifier (required)
user = client.getUser(id_user)
GET /user/:id_user HTTP/1.1

Sample JSON response

{
 "_id": "558818da01e0ef01006e979b",
 "description": "annotator",
 "role": "user",
 "username": "johndoe"
}

update one user

PUT /user/:id_user

QUERY PARAMETERS

Parameter Type Description
id_user String The user identifier (required)

DATA PARAMETERS

Key Type Description
password String The password
description free A description of the user
role String The user role (“admin” or “user”)
PUT /user/:id_user HTTP/1.1

{'description': 'expert annotator'}
user = client.updateUser(id_user,
                         password='password',
                         description={'number': 42},
                         role='admin')

Sample JSON response

{
 "_id": "558818da01e0ef01006e979b",
 "description": "expert annotator",
 "role": "user",
 "username": "johndoe"
}

get one user’s groups

GET /user/:id_user/group

QUERY PARAMETERS

Parameter Type Description
id_user String The user identifier (required)
GET /user/:id_user/group HTTP/1.1
id_groups = client.getUserGroups(id_user)

Sample JSON response

[
 "55881d1601e0ef01006e979c"
]

get all groups

GET /group

DATA PARAMETERS

Key Type Description
name String filter groups by name (optional)
GET /group HTTP/1.1

{'name': 'project'}
groups = client.getGroups()

Sample JSON response

[
 {
  "_id": "55881d1601e0ef01006e979c",
  "description": "members of the project",
  "name": "project",
  "users": ["558818da01e0ef01006e979b", "55881d6001e0ef01006e979d"]
 }
]

get one group

GET /group/:id_group

QUERY PARAMETERS

Parameter Type Description
id_group String The group identifier (required)
GET /group/:id_group HTTP/1.1
group = client.getGroup(id_group)

Sample JSON response

{
  "_id": "55881d1601e0ef01006e979c",
  "description": "members of the project",
  "name": "project",
  "users": ["558818da01e0ef01006e979b", "55881d6001e0ef01006e979d"]
}

create new group

POST /group

DATA PARAMETERS

Key Type Description
name String The group name (can’t be updated)
description free A description of the group
POST /group HTTP/1.1

{'name': 'guests'}
group = client.createGroup(
  'limsi', 
  description={'affiliation': 'LIMSI'})

Sample JSON response

{
 "_id": "55881f8301e0ef01006e979e",
 "description": "",
 "name": "guests",
 "users": []
}

update one group

PUT /group/:id_group

QUERY PARAMETERS

Parameter Type Description
id_group String The group identifier (required)

DATA PARAMETERS

Key Type Description
description free A description of the group
PUT /group/:id_group HTTP/1.1

{ 'description': 'open trial'}
group = client.updateGroup(
  id_group, 
  description={'affiliation': 'LIMSI/CNRS'})

Sample JSON response

{
 "_id": "55881f8301e0ef01006e979e",
 "description": "open trial",
 "name": "guests",
 "users": []
}

delete one group

DELETE /group/:id_group

QUERY PARAMETERS

Parameter Type Description
id_group String The group identifier (required)
DELETE /group/:id_group HTTP/1.1
client.deleteGroup(id_group)

JSON response upon success

{
 "success": "Successfully deleted."
}

add one user to one group

PUT /group/:id_group/user/:id_user

QUERY PARAMETERS

Parameter Type Description
id_group String The group identifier (required)
id_user String The user identifier (required)
PUT /group/:id_group/user/:id_user HTTP/1.1
client.addUserToGroup(id_user, id_group)

Sample JSON response

{
  "_id": "55881d1601e0ef01006e979c",
  "description": "members of the project",
  "name": "project",
  "users": ["558818da01e0ef01006e979b", "55881d6001e0ef01006e979d"]
}

remove one user from one group

DELETE /group/:id_group/user/:id_user

QUERY PARAMETERS

Parameter Type Description
id_group String The group identifier (required)
id_user String The user identifier (required)
client.removeUserFromGroup(id_user, id_group)
DELETE /group/:id_group/user/:id_user HTTP/1.1

Sample JSON response

{
  "_id": "55881d1601e0ef01006e979c",
  "description": "members of the project",
  "name": "project",
  "users": ["558818da01e0ef01006e979b"]
}

Corpora

get all READable corpora

GET /corpus

corpora = client.getCorpora()
GET /corpus HTTP/1.1

Sample JSON response

[
 {
  "_id": "555daefff80f910100d741d6",
  "description": "Test corpus",
  "name": "ctest"
 }
]

get one corpus

GET /corpus/:id_corpus

QUERY PARAMETERS

Parameter Type Description
id_corpus String The corpus identifier (required)
corpus = client.getCorpus(id_corpus)
GET /corpus/:id_corpus HTTP/1.1

Sample JSON response

{
  "_id": "555daefff80f910100d741d6",
  "description": "Test corpus",
  "name": "ctest"
}

create new corpus

POST /corpus

DATA PARAMETERS

Key Type Description
name String The corpus name (unique)
description free A description of the corpus
corpus = client.createCorpus(
  'unique name', 
  description={'license': 'Creative Commons'})
POST /corpus HTTP/1.1

{'name': 'unique name', 'description': {'license': 'Creative Commons'}}

Sample JSON response

{
 "_id": "555daefff80f910100d741d6",
 "description": {"license": "Creative Commons"},
 "name": "unique name"
}

update one corpus

PUT /corpus/:id_corpus

QUERY PARAMETERS

Parameter Type Description
id_corpus String The corpus identifier (required)

DATA PARAMETERS

Key Type Description
name String The corpus name (unique)
description free A description of the corpus
corpus = client.updateCorpus(
  id_corpus, 
  name='new name', 
  description={'license': 'MIT'})
PUT /corpus/:id_corpus HTTP/1.1

{'description': {'license': 'MIT'},
 'name': 'new name'}

Sample JSON response

{
 "_id": "555daefff80f910100d741d6",
 "description": {"license": "MIT"},
 "name": "new name"
}

delete one corpus

DELETE /corpus/:id_corpus

QUERY PARAMETERS

Parameter Type Description
id_corpus String The corpus identifier (required)
client.deleteCorpus(id_corpus)
DELETE /corpus/:id_corpus HTTP/1.1

JSON response upon success

{
 "success": "Successfully deleted."
}

get one corpus’ permissions

GET /corpus/:id_corpus/permissions

QUERY PARAMETERS

Parameter Type Description
id_corpus String The corpus identifier (required)
GET /corpus/:id_corpus/permissions HTTP/1.1
permissions = client.getCorpusPermissions(id_corpus)

Sample JSON response

{
  "users": [
    "5423dc0900e5c11a8fc723ba",
    "5423dc0900e5c11a8fc723bb"
  ],
  "groups": [
    "5423dfeb00e5c11a8fc723bc",
  ]
}

give one user permissions to one corpus

PUT /corpus/:id_corpus/user/:id_user

QUERY PARAMETERS

Parameter Type Description
id_corpus String The corpus identifier (required)
id_user String The user identifier (required)

DATA PARAMETERS

Key Type Description
right 1, 2 or 3 The corpus permissions (1:READ, 2:WRITE, 3:ADMIN)
client.setCorpusPermissions(id_corpus, client.ADMIN, user=id_user)
PUT /corpus/:id_corpus/user/:id_user HTTP/1.1
{'right': 3}

Sample JSON response

{
  "users": {"555299eff80f910100d741d1": 3,
  "5552bf5cf80f910100d741d2": 2,
  "55881d6001e0ef01006e979d": 3}
}

remove one user’s permissions to one corpus

DELETE /corpus/:id_corpus/user/:id_user

QUERY PARAMETERS

Parameter Type Description
id_corpus String The corpus identifier (required)
id_user String The user identifier (required)
client.removeCorpusPermissions(id_corpus, user=id_user)
DELETE /corpus/:id_corpus/user/:id_user HTTP/1.1

Sample JSON response

{
 "users": {"555299eff80f910100d741d1": 3,
  "5552bf5cf80f910100d741d2": 2}
}

give one group permissions to one corpus

PUT /corpus/:id_corpus/group/:id_group

QUERY PARAMETERS

Parameter Type Description
id_corpus String The corpus identifier (required)
id_group String The group identifier (required)

DATA PARAMETERS

Key Type Description
right 1, 2 or 3 The corpus permissions (1:READ, 2:WRITE, 3:ADMIN)
client.setCorpusPermissions(id_corpus, ADMIN, group=id_group)
PUT /corpus/:id_corpus/group/:id_group HTTP/1.1

Sample JSON response

{
 "groups": {"55881d1601e0ef01006e979c": 2},
 "users": {"555299eff80f910100d741d1": 3, 
   "5552bf5cf80f910100d741d2": 2}
}

remove one group’s permissions to one corpus

DELETE /corpus/:id_corpus/group/:id_group

QUERY PARAMETERS

Parameter Type Description
id_corpus String The corpus identifier (required)
id_group String The group identifier (required)
client.removeCorpusPermissions(id_corpus, group=id_group)
DELETE /corpus/:id_corpus/group/:id_group HTTP/1.1

Sample JSON response

{
 "users": {"555299eff80f910100d741d1": 3,
  "5552bf5cf80f910100d741d2": 2}
}

Media

get all media

GET /medium

DATA PARAMETERS

Key Type Description
name String filter media by name
client.getMedia()
GET /medium HTTP/1.1

Sample JSON response

[
 {"_id": "...", "description": "", "id_corpus": "...", "name": "show1", "url": ""},
 {"_id": "...", "description": "", "id_corpus": "...", "name": "show2", "url": ""}
 ...
]

get one medium

GET /medium/:id_medium`

QUERY PARAMETERS

Parameter Type Description
id_medium String The medium identifier (required)
client.getMedium(id_medium)
GET /medium/:id_medium HTTP/1.1

Sample JSON response

{
  "_id": "555db2e6f80f910100d741d8",
  "description": "",
  "id_corpus": "555daefff80f910100d741d6",
  "name": "LCP_PileEtFace_2012-11-30_012500",
  "url": ""
}

get one corpus’ media

GET /corpus/:id_corpus/medium

QUERY PARAMETERS

Parameter Type Description
id_corpus String The corpus identifier (required)

DATA PARAMETERS

Key Type Description
name String filter media by name
client.getMedia(id_corpus)
GET /corpus/:id_corpus/medium HTTP/1.1

Sample JSON response

{
  "_id": "555db2e6f80f910100d741d8",
  "description": "",
  "id_corpus": "555daefff80f910100d741d6",
  "name": "LCP_PileEtFace_2012-11-30_012500",
  "url": ""
}

create new medium(a) in one corpus

POST /corpus/:id_corpus/medium

QUERY PARAMETERS

Parameter Type Description
id_corpus String The corpus identifier (required)

DATA PARAMETERS

Key Type Description
name String The medium name (unique)
url String absolute or relative URL to the medium
description free A description of the medium

OR list of {name, url, description}

client.createMedium(id_corpus, name, url, description)

media = [{'name':'show1'}, {'name':'show2'}]
client.createMedia(id_corpus, media)
POST /corpus/:id_corpus/medium HTTP/1.1

{'name': 'LCP_PileEtFace_2012-11-30_012500'}

Sample JSON response

{
 "_id": "55895e90c70125010026f6b5",
 "id_corpus": "558955cec70125010026f6aa",
 "name": "LCP_PileEtFace_2012-11-30_012500",
 "url": ""
}

update one medium

PUT /medium/:id_medium

QUERY PARAMETERS

Parameter Type Description
id_medium String The medium identifier (required)

DATA PARAMETERS

Key Type Description
name String The medium name (unique)
url String absolute or relative URL to the medium
description free A description of the medium
client.updateMedium(id_medium, name, url, description)
PUT /medium/:id_medium HTTP/1.1

{'description': 'LCP channel'}

Sample JSON response

{
 "_id": "55895e90c70125010026f6b5",
 "id_corpus": "558955cec70125010026f6aa",
 "name": "LCP_PileEtFace_2012-11-30_012500",
 "url": "",
 "description": "LCP channel"
}

delete one medium

DELETE /medium/:id_medium

QUERY PARAMETERS

Parameter Type Description
id_medium String The medium identifier (required)
client.deleteMedium(id_medium)
DELETE /medium/:id_medium HTTP/1.1

JSON response upon success

{
 "success": "Successfully deleted."
}

stream one medium in default format

GET /medium/:id_medium/video

QUERY PARAMETERS

Parameter Type Description
id_medium String The medium identifier (required)
client.streamMedium(id_medium)
GET /medium/:id_medium/video HTTP/1.1

stream one medium in WebM, MP4 or OGV

GET /medium/:id_medium/{webm,mp4,ogv}

QUERY PARAMETERS

Parameter Type Description
id_medium String The medium identifier (required)
client.streamMedium(id_medium, format='webm')
client.streamMedium(id_medium, format='mp4')
client.streamMedium(id_medium, format='ogv')
GET /medium/:id_medium/webm HTTP/1.1

GET /medium/:id_medium/mp4 HTTP/1.1

GET /medium/:id_medium/ogv HTTP/1.1

Layers

get all layers

GET /layer

DATA PARAMETERS

Key Type Description
name String filter layers by name (optional)
fragment_type String filter layers by fragment type (optional)
data_type String filter layers by data type (optional)
GET /layer HTTP/1.1
layers = client.getLayers()

Sample JSON response

{

}

get one layer

GET /layer/:id_layer

QUERY PARAMETERS

Parameter Type Description
id_layer String The layer identifier (required)
GET /layer/:id_layer HTTP/1.1
layer = client.getLayer(id_layer)

Sample JSON response

{

}

get one corpus’ layers

GET /corpus/:id_corpus/layer

QUERY PARAMETERS

Parameter Type Description
id_corpus String The corpus identifier (required)

DATA PARAMETERS

Key Type Description
name String filter layers by name (optional)
fragment_type String filter layers by fragment type (optional)
data_type String filter layers by data type (optional)
GET /corpus/:id_corpus/layer HTTP/1.1
layer = client.getLayers(id_corpus)

Sample JSON response

{

}

create new layer(s) in one corpus

POST /corpus/:id_corpus/layer

QUERY PARAMETERS

Parameter Type Description
id_corpus String The corpus identifier (required)

DATA PARAMETERS

Key Type Description
name String layer name (required)
description free layer description (optional)
fragment_type free layer fragment type (optional)
data_type free layer data type (optional)
annotations list list of annotations (optional)
POST /corpus/:id_corpus/layer HTTP/1.1
client.createLayer(id_corpus, name, description, fragment_type, data_type, annotations)

Sample JSON response

{

}

update one layer

PUT /layer/:id_layer

QUERY PARAMETERS

Parameter Type Description
id_layer String The layer identifier (required)

DATA PARAMETERS

Key Type Description
name String layer name (optional)
description free layer description (optional)
fragment_type free layer fragment type (optional)
data_type free layer data type (optional)
PUT /layer/:id_layer HTTP/1.1
client.updateLayer(id_layer, name, description, fragment_type, data_type)

Sample JSON response

{

}

delete one layer

DELETE /layer/:id_layer

QUERY PARAMETERS

Parameter Type Description
id_layer String The layer identifier (required)
DELETE /layer/:id_layer HTTP/1.1
client.deleteLayer(id_layer)

Sample JSON response

{

}

get one layer’s permissions

GET /layer/:id_layer/permissions

QUERY PARAMETERS

Parameter Type Description
id_layer String The layer identifier (required)
GET /layer/:id_layer/permissions HTTP/1.1
permission = client.getLayerPermissions(id_layer)

Sample JSON response

{

}

give one user permissions to one layer

PUT /layer/:id_layer/user/:id_user

QUERY PARAMETERS

Parameter Type Description
id_layer String The layer identifier (required)
id_user String The user identifier (required)

DATA PARAMETERS

Key Type Description
right 1, 2 or 3 The layer permissions (1:READ, 2:WRITE, 3:ADMIN)
PUT /layer/:id_layer/user/:id_user HTTP/1.1
client.setLayerPermissions(id_layer, permission, user=id_user)

Sample JSON response

{

}

remove one user’s permissions to one layer

DELETE /layer/:id_layer/user/:id_user

QUERY PARAMETERS

Parameter Type Description
id_layer String The layer identifier (required)
id_user String The user identifier (required)
DELETE /layer/:id_layer/user/:id_user HTTP/1.1
client.removeLayerPermissions(id_layer, permission, user=id_user)

Sample JSON response

{

}

give one group permissions to one layer

PUT /layer/:id_layer/group/:id_group

QUERY PARAMETERS

Parameter Type Description
id_layer String The layer identifier (required)
id_group String The group identifier (required)

DATA PARAMETERS

Key Type Description
right 1, 2 or 3 The layer permissions (1:READ, 2:WRITE, 3:ADMIN)
PUT /layer/:id_layer/group/:id_group HTTP/1.1
client.setLayerPermissions(id_layer, permission, group=id_group)

Sample JSON response

{

}

remove on group’s permissions to one layer

DELETE /layer/:id_layer/group/:id_group

QUERY PARAMETERS

Parameter Type Description
id_layer String The layer identifier (required)
id_group String The group identifier (required)
DELETE /layer/:id_layer/group/:id_group HTTP/1.1
client.removeLayerPermissions(id_layer, permission, group=id_group)

Sample JSON response

{

}

Annotations

get all annotations

GET /annotation

DATA PARAMETERS

Key Type Description
id_medium String filter annotations by medium (optional)
fragment String filter annotations by fragment (optional)
data String filter annotations by data (optional)
GET /annotation HTTP/1.1
client.getAnnotations(medium=id_medium, fragment=fragment, data=data)

Sample JSON response

{

}

get one annotation

GET /annotation/:id_annotation

QUERY PARAMETERS

Parameter Type Description
id_annotation String The annotation identifier (required)
GET /annotation/:id_annotation HTTP/1.1
client.getAnnotation(id_annotation)

Sample JSON response

{

}

get one layer’s annotations

GET /layer/:id_layer/annotation

QUERY PARAMETERS

Parameter Type Description
id_layer String The layer identifier (required)

DATA PARAMETERS

Key Type Description
id_medium String filter annotations by medium (optional)
fragment String filter annotations by fragment (optional)
data String filter annotations by data (optional)
GET /layer/:id_layer/annotation HTTP/1.1
client.getAnnotations(id_layer, medium=id_medium, fragment=fragment, data=data)

Sample JSON response

{

}

create new annotation(s) in one layer

POST /layer/:id_layer/annotation

QUERY PARAMETERS

Parameter Type Description
id_layer String The layer identifier (required)

DATA PARAMETERS

Key Type Description
id_medium String medium identifier (required)
fragment free annotation fragment (required)
data free annotation data (required)

OR

list of {id_medium:…, fragment:…, data:…}

POST /layer/:id_layer/annotation HTTP/1.1
client.createAnnotation(id_layer, medium=id_medium, fragment=fragment, data=data)

OR

client.createAnnotations(id_layer,annotations)

Sample JSON response

{

}

update one annotation

PUT /annotation/:id_annotation

QUERY PARAMETERS

Parameter Type Description
id_annotation String The annotation identifier (required)

DATA PARAMETERS

Key Type Description
fragment free annotation fragment (optional)
data free annotation data (optional)
PUT /annotation/:id_annotation HTTP/1.1
client.updateAnnotation(id_annotation, fragment=fragment, data=data)

Sample JSON response

{

}

delete one annotation

DELETE /annotation/:id_annotation

QUERY PARAMETERS

Parameter Type Description
id_annotation String The annotation identifier (required)
DELETE /annotation/:id_annotation HTTP/1.1
client.deleteAnnotation(id_annotation)

Sample JSON response

{

}

Queues

get all queues

GET /queue

DATA PARAMETERS

Key Type Description
name String queue name (optional)
GET /queue HTTP/1.1
queues = client.getQueues()

Sample JSON response

[
  {
    "_id": "5423dc0900e5c11a8fc723bb",
    "name": "name",
    "description": {"my": "description"},
    "list": ["item1", "item2"]
  },
  ...
]

get one queue

GET /queue/:id_queue

QUERY PARAMETERS

Parameter Type Description
id_queue String The queue identifier (required)
GET /queue/:id_queue HTTP/1.1
queues = client.getQueue(id_queue)

Sample JSON response

{
  "_id": "5423dc0900e5c11a8fc723bb",
  "name": "name",
  "description": {"my": "description"},
  "list": ["item1", "item2"]
}

create new queue

POST /queue

DATA PARAMETERS

Key Type Description
name String queue name (required)
description free queue description (optional)
POST /queue HTTP/1.1
queue = client.createQueue('queue name', description={'my': 'description'})

Sample JSON request

{
  "name": "name",
  "description": {"my": "description"}
}

Sample JSON response

{
  "_id": "5423dc0900e5c11a8fc723bb",
  "name": "name",
  "description": {"my": "description"},
  "list": []
}

update one queue

PUT /queue/:id_queue

QUERY PARAMETERS

Parameter Type Description
id_queue String The queue identifier (required)

DATA PARAMETERS

Key Type Description
name String queue name (optional)
description free queue description (optional)
list list list of new queue elements (optional)
PUT /queue/:id_queue HTTP/1.1
queue = client.updateQueue(id_queue, 
  name='new name', description={'new': 'description'},
  elements=['item1', 'item2'])

Sample JSON request

{
  "name": "new name",
  "description": {"new": "description"},
  "list": ["item1", "item2"]
}

Sample JSON response

{
  "_id":"5423dc0900e5c11a8fc723bb",
  "name": "new name",
  "description": {"new": "description"},
  "list": ["item1", "item2"]
}

append item(s) to one queue

PUT /queue/:id_queue/next

QUERY PARAMETERS

Parameter Type Description
id_queue String The queue identifier (required)

DATA PARAMETERS

Type Description
list list of queue elements
PUT /queue/:id_queue/next HTTP/1.1
queue = client.enqueue(id_queue, items)

Sample JSON response

{

}

pop one item from one queue

GET /queue/:id_queue/next

QUERY PARAMETERS

Parameter Type Description
id_queue String The queue identifier (required)
GET /queue/:id_queue/next HTTP/1.1
item = client.dequeue(id_queue)

get next item on one queue (without actually removing it)

(Non-destructively) pick first element of queue

GET /queue/:id_queue/first

QUERY PARAMETERS

Parameter Type Description
id_queue String The queue identifier (required)
GET /queue/:id_queue/first HTTP/1.1
item = client.pick(id_queue)

get number of items in one queue

(Non-destructively) get number of elements in queue

GET /queue/:id_queue/length

QUERY PARAMETERS

Parameter Type Description
id_queue String The queue identifier (required)
GET /queue/:id_queue/length HTTP/1.1
item = client.pickLength(id_queue)

get all items from one queue

(Non-destructively) pick all elements of queue

GET /queue/:id_queue/all

QUERY PARAMETERS

Parameter Type Description
id_queue String The queue identifier (required)
GET /queue/:id_queue/all HTTP/1.1
item = client.pickAll(id_queue)

remove one queue

DELETE /queue/:id_queue

QUERY PARAMETERS

Parameter Type Description
id_queue String The queue identifier (required)
DELETE /queue/:id_queue HTTP/1.1
client.deleteQueue(id_corpus)

Sample JSON response

{
  "success": "Successfully deleted."
}

get one queue’s permissions

GET /queue/:id_queue/permissions

QUERY PARAMETERS

Parameter Type Description
id_queue String The queue identifier (required)
GET /queue/:id_queue/permissions HTTP/1.1
client.getQueuePermissions(id_queue)

Sample JSON response

{

}

give one user permissions to one queue

PUT /queue/:id_queue/user/:id_user

QUERY PARAMETERS

Parameter Type Description
id_queue String The queue identifier (required)
id_user String The user identifier (required)

DATA PARAMETERS

Key Type Description
right 1, 2 or 3 The queue permissions (1:READ, 2:WRITE, 3:ADMIN)
PUT /queue/:id_queue/user/:id_user HTTP/1.1
client.setQueuePermissions(id_queue, client.WRITE, user=id_user)

Sample JSON response

{

}

remove one user’s permissions to one queue

DELETE /queue/:id_queue/user/:id_user

QUERY PARAMETERS

Parameter Type Description
id_queue String The queue identifier (required)
id_user String The user identifier (required)
DELETE /queue/:id_queue/user/:id_user HTTP/1.1
client.removeQueuePermissions(id_queue, user=id_user)

Sample JSON response

{

}

give one group permissions to one queue

PUT /queue/:id_queue/group/:id_group

QUERY PARAMETERS

Parameter Type Description
id_queue String The queue identifier (required)
id_group String The group identifier (required)

DATA PARAMETERS

Key Type Description
right 1, 2 or 3 The queue permissions (1:READ, 2:WRITE, 3:ADMIN)
PUT /queue/:id_queue/group/:id_group HTTP/1.1
client.setQueuePermissions(id_queue, client.WRITE, group=id_group)

Sample JSON response

{

}

remove on group’s permissions to one queue

DELETE /queue/:id_queue/group/:id_group

QUERY PARAMETERS

Parameter Type Description
id_queue String The queue identifier (required)
id_group String The group identifier (required)
DELETE /queue/:id_queue/group/:id_group HTTP/1.1
client.removeQueuePermissions(id_queue, group=id_group)

Sample JSON response

{

}

Metadata

Metadata is only available for Corpus, Layer and Medium

get

GET /:resource_type/:resource_id/metadata/:path

QUERY PARAMETERS

Parameter Type Description
resource_type String The resource type (corpus, layer or medium) (required)
resource_id String The resource identifier (required)
path String The metadata path, if not set return first level keys (optional)

DATA PARAMETERS FOR FILE

Parameter Type Description
type String set to file
filename String filename
data String Base64 encoded file content (Only set if last level and not ?file parameter)
client.getCorpusMetadata(
  '555daefff80f910100d741d6', 
  'level1')
GET /corpus/555daefff80f910100d741d6/metadata/level1 HTTP/1.1

# Or for download file

GET /corpus/555daefff80f910100d741d6/metadata/my.picture?file HTTP/1.1

Camomile.getCorpusMetadata('555daefff80f910100d741d6', 'test2.child', function(err, datas) {
    console.log(datas);
});

Sample JSON response

{
 "mykey": "value",
 "myarray": ["value1", "value2"],
 "myobject": {"mykey": "myvalue"}
}

File “`json { "myfile”: { “filename”: “myvalue”, “type”: “file”

} } “`

get first level keys

GET /:resource_type/:resource_id/metadata/:path*.*

End path with .

QUERY PARAMETERS

Parameter Type Description
resource_type String The resource type (corpus, layer or medium) (required)
resource_id String The resource identifier (required)
path String The metadata path, if not set return first level keys (optional)
client.getCorpusMetadataKeys(
  '555daefff80f910100d741d6', 
  'level1')
Camomile.getCorpusMetadataKeys('555daefff80f910100d741d6', function(err, datas) {
    console.log(datas);
});

Camomile.getCorpusMetadataKeys('555daefff80f910100d741d6', 'level1', function(err, datas) {
    console.log(datas);
});
GET /corpus/555daefff80f910100d741d6/metadata/level1. HTTP/1.1

Sample JSON response

[
 "mykey"
 "myarray"
 "myobject"
]

create / update

POST /:resource_type/:resource_id/metadata/

QUERY PARAMETERS

Parameter Type Description
resource_type String The resource type (corpus, layer or medium) (required)
resource_id String The resource identifier (required)
client.setCorpusMetadata(
  '555daefff80f910100d741d6', 
  {'name': 'my metadata', 'level1': {'my_array': ['value1', 'value2']}})

  #OR

  client.setCorpusMetadata(
    '555daefff80f910100d741d6',
    datas="myvalue",
    path="my.key")
POST /corpus/555daefff80f910100d741d6/metadata/ HTTP/1.1

{"name": "my metadata", "level1": {"my_array": ["value1", "value2"]}}

Camomile.setCorpusMetadata(
    '555daefff80f910100d741d6', 
    {'name': 'my metadata', 'level1': {'my_array': ['value1', 'value2']}} , 
    function(err, success) {
        console.log(success);
    }
);

Sample JSON response

{
 "success": "Successfully created."
}

create / update file

POST /:resource_type/:resource_id/metadata/

Send base64 encoded file

QUERY PARAMETERS

Parameter Type Description
resource_type String The resource type (corpus, layer or medium) (required)
resource_id String The resource identifier (required)

DATA PARAMETERS

Parameter Type Description
type String set to file (required)
filename String filename (required)
data String Base64 encoded file content (required)
client.sendCorpusMetadataFile(
  '555daefff80f910100d741d6', 
  'level1.mypicture',
  '/path/to/file.ext')
var inputFile = document.getElementById('file');
var file = inputFile.files[0];

Camomile.sendCorpusMetadataFile(
    '555daefff80f910100d741d6', 
    'level1.mypicture', 
    file, 
    function(err, success) {
        console.log(success);
    }
);
POST /corpus/555daefff80f910100d741d6/metadata/ HTTP/1.1

{'level1': {'mypicture': {'type': 'file', 'filename': 'file.ext', 'data': '<base64_encoded_file>'}}}

Sample JSON response

{
 "success": "Successfully created."
}

delete

DELETE /corpus/555daefff80f910100d741d6/metadata/:path

Parameter Type Description
resource_type String The resource type (corpus, layer or medium) (required)
resource_id String The resource identifier (required)
path String The metadata path (required)
client.deleteCorpusMetadata(
  '555daefff80f910100d741d6', 
  'level1')
DELETE /corpus/555daefff80f910100d741d6/metadata/level1 HTTP/1.1

Camomile.deleteCorpusMetadata('555daefff80f910100d741d6', 'level1', function(err, success) {
    console.log(success);
});

Sample JSON response

{
 "success": "Successfully deleted."
}

Server Sent Event

Server Sent Event is only available for Corpus, Layer, Medium and Queue

Available events

Corpus

Layer

Medium

Queue

get an available channel

POST /listen

POST /listen HTTP/1.1

Sample JSON response

{
 "channel_id": 10
}

Connect to SSE entrypoint

GET /listen/:channel_id

Parameter Type Description
channel_id Integer Channel identifier (required)

Watch resource

PUT /listen/:channel_id/:resource_type/:resource_id

def callback(event):
    print event

client.watchCorpus('555daefff80f910100d741d6', callback)
Camomile.listen(function(error, channel_id, event) {
    var unwatchCorpus = event.watchCorpus('555daefff80f910100d741d6', function(error, data) {
        console.log(data);

        // For unwatch corpus:
        unwatchCorpus();
    });
});
PUT /listen/5/medium/555daefff80f910100d741d6 HTTP/1.1

Sample JSON response

{
 "event": "medium:555daefff80f910100d741d6"
}

Unwatch resource

DELETE /listen/:channel_id/:resource_type/:resource_id

client.unwatchCorpus('555daefff80f910100d741d6')
DELETE /listen/5/medium/555daefff80f910100d741d6 HTTP/1.1

Sample JSON response

{
 "success": "Successfully unwatched."
}

Miscellaneous

get current date/time

GET /date

GET /date HTTP/1.1

Sample JSON response

{

}
client.date()