-
Notifications
You must be signed in to change notification settings - Fork 4
Plugin requirements
- A POST request containing, in the request header, a JSON-encoded set of artifact IDs along with synonyms, like this:
{
<id>: {
"url":<url>,
"pmid":<pubmed id>
},
<id>: {
"url":<url>,
"pmid":<pubmed id>
},
...
}
For external plugins (running on other people's servers), the mechanics of this are not our concern. For local plugins, though, we need to handle the REST interface. To do this, Jason is replacing the old system with this one: each plugin is an appropriately-named directory. Each directory contains index.php, which for Python plugins will contain this:
<?php
$pluginName = "plugin.py";
$idsJsonStr = escapeshellarg($_POST);
echo exec('python ' . $pluginName . ' ' . $idsJsonStr);
?>
This is nothing more than a wrapper that calls the Python code and prints the output. The advantage to this is that plugin writers fluent in Python can control the entire behaviour of their plugins, and there is clear division of responsibility. The plugin directory is entirely self-contained and calls no other code.
- filter those IDs so that only relevant ones are sent to Source API
- for each relevant ID, note what type of artifact it is (article, slideshow, etc)
- chunk them together if their Source API gets down like that
- make as many calls as needed to their Source API to get data on everything.
- pause before each call, if needed to handle rate limiting (eg, for Delicious)
- do error checking on what they get back from the Source and handle things appropriately
- Plugins should use exponential backoff to handle bad responses from Source APIs. For now, the maximum wait interval should be 5 minutes or so, then an error should be thrown.
- For now, errors should be reported by returning a JSON object like this:
{"error": "<text of error message>"}
. In the future, we can use error codes. - In the future, plugins may want to cache responses
- Plugins may want to log reponses
Plugins return a flat array of events, possibly of different types. Each event is an object with these attributes (note the addition of a timestamp, so we know how fresh it is and can gather others over time):
{
"source_name": "Mendeley",
"last_update": "1306599479", // unix timestamp as string
"error": "API limit reached" // set to false if no error
"about": {
"descr": "A research management tool for desktop and web.",
"url": "http://www.mendeley.com/",
"icon": "http://www.mendeley.com/favicon.ico",
"metrics": {
"readers": "the number of readers of the article",
"groups": "the number of groups the article is in"
}
},
"artifacts": { // only return artifacts the plugin can grok (eg, this plugin would discard URLs)
"10.1371/journal.pbio.0060048": {
"type": "article", // required for all plugins; all other attributes are plugin-specific, and match the list in about.metrics
"readers": 24, // can be int (including 0) or string
"groups": 3
},
"10.1371/journal.pone.00008109": {
"type": "article",
"readers": 0,
"groups": 0
}
}
}