Reputation: 785
I've stumbled across an awesome open source project called openCPU.org and I'm tremendously excited about the project. As a research scientist trying to create a website hosting my work, I would love nothing more than to be able to run R on the cloud to have my scripts run in real time and show up on my webpages. So a big time thanks to Jeroen for making this project happen.
With that, onto my question.
How the heck do I interact with openCPU?
I can put an example function into "run some code" at:
http://public.opencpu.org/userapps/opencpu/opencpu.demo/runcode/
And retrieve a PNG image of my code, which is great!
But how do I do that in my own webpage, or via a URL?
I can get the object of my original code upload from this page, something like: "x3ce3bf3e33"
If it is a function similar to:
myfun <-function(){
x = seq(1,6.28)
y = cos(x)
p = plot(x,y)
print(p)
# also tried return(p)
}
Shouldn't I be able to call it via:
http://public.opencpu.org/R/tmp/x3ce3bf3e33/png
What about with input variables? e.g.:
myfun <-function(foo){
x = seq(1,foo)
y = cos(x)
p = plot(x,y)
print(p)
}
I feel that perhaps there is something I am missing. How do I specify "GET" or "POST" with the url?
EDIT
Ok in response to @Jeroen below, I need to use to use POST and GET with the API. Now my question is extend to the following issue of getting PHP to interact with it correctly.
Say I have the code:
<?php
$foo = 'bar';
$options = array(
'method' => 'POST',
'foo' => $foo,
);
$url = "http://public.opencpu.org/R/tmp/x0188b9b9ce/save";
$result = drupal_http_request($url,$options); // drupal function
?>
How do I then access what is passed back in $result? I am looking to get a graph. It looks like this:
{
"object" : null,
"graphs" : [
"x2acba9501a"
],
"files" : {}
}
The next step will be to GET the image, something along the lines of:
$newurl = "http://public.opencpu.org/R/tmp/".$result["graph"]."/png";
$image = drupal_http_request($newurl);
echo $image;
But I don't know how to access the individual elements of $result?
EDIT #2
Ok guys, I've gotten this to work, thanks to the answer below and to multiple other help sessions, and a lot of smashing my head against the monitor.
Here we go, done with cURL
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://public.opencpu.org/R/tmp/x0188b9b9ce/save');
curl_setopt($ch, CURLOPT_POST, 1); // Method is "POST"
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // Returns the curl_exec string, rather than just Logical value
$result = curl_exec($ch);
curl_close($ch);
$new = json_decode($result,true); // $result is in 'json' format, decode it
$get = $new['graphs'][0]; // the 'hashkey for the image, "x2acba9501a" above
$img = 'http://public.opencpu.org/R/tmp/'.$get.'/png'; // link to the png image
echo <<<END // use this to display an image from the url
<a href="$img">
<img src="$img">
</a>
END
?>
Upvotes: 2
Views: 1937
Reputation: 686
Here is a complete example webpage I mocked up to use OpenCPU to demo a particular analysis using a R package I wrote (MARSS). I was monkeying with providing easy access to particular analyses--a live user guide so to speak. Caveat, my example relies heavily on JavaScript and I've no experience with JavaScript beyond this example; so the coding is clunky but it works for my purposes. Copy and paste the html into a file and open in a browser and it should work.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
html, body
{
background: #6699FF;
text-align: center;
font-family : "Lucida Sans Unicode", "Lucida Grande", sans-serif;
font-size:14px;
}
#container
{
background: #FFF;
border: 0px #222 solid;
margin: 0 auto;
text-align: left;
width: 10.25in;
padding: 5px;
overflow: auto;
}
#container form
{
margin: 0 auto;
}
label
{
float: left;
width: 50px;
}
.leftCol
{
float: left;
width: 3in;
}
.rightCol
{
float: left;
width: 7in;
}
.references
{
font-size: x-small;
text-indent: 20px;
}
</style>
<base target="_blank" />
<title>Count-based population viability analysis (PVA) using corrupted data</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"> </script>
<script>
baseurl="http://public.opencpu.org"
// This is done on load since we need the function on the server to deal with the file upload
function saveRFunction(){
//Run this bit of code and store the R function to run on OpenCPU
var baseurl = "http://public.opencpu.org";
var url = "http://public.opencpu.org/R/pub/base/identity/save";
// #txtRCommands is the id of the text box in the javascript
var rFunction = $("#RFunction").val();
// this bit sends the the RFunction in the hidden text area
$.post(url,{ x: rFunction },
function (data) {
var funloc = $.parseJSON(data).object;
funloc = "http://public.opencpu.org/R/tmp/"+funloc;
//set the action for the form
document.getElementById('FunctionLocation').value = funloc;
} );
setTimeout(function() {
// Wait 2 seconds because of Chrome before loading default form
var frm = document.getElementById("inputForm2");
subm2(frm,'/svg');
}, 1000);
};
//function for first submit button; subm and subm2 same except the id
function subm(f,ftype){
document.getElementById("inputForm").action=document.getElementById('FunctionLocation').value+ftype;
f.submit();
}
function subm2(f,ftype){
document.getElementById("inputForm2").action=document.getElementById('FunctionLocation').value+ftype;
f.submit();
}
</script>
</head>
<body onload="saveRFunction()">
<div id="container">
<h2>MARSS Case Study 1: Count-based PVA for data with observation error</h2>
This web tool fits a count-based PVA model (sensu Dennis et al. 1991) from a univariate (one site) time series of abundance data with observation error (Holmes 2001, 2004). The result is an estimated long-term rate of population growth (λ), process variance estimate (σ<sup>2</sup>) and non-process or observation error variance. Extinction risk metrics sensu Dennis et al. (1991) along with an uncertainty plot sensu Ellner and Holmes (2008) are shown.
</br></br>
<div class="leftCol">
<form enctype="multipart/form-data" action="" method="POST" target="test" id="inputForm">
<fieldset>
<legend><b>Upload a Dataset</b></legend>
<i>Comma-delimited. 1st col time, 2nd col counts. Missing counts NA.</i></br>
File: <input name="!file:file" type="file" /> <!-- param name has to be file -->
Header: <select name="header"><option value=TRUE> TRUE </option> <option value=FALSE> FALSE </option> </select> </br />
<input name="!width" type="hidden" value=7 /> <!-- in inches -->
<input name="!height" type="hidden" value=6 /> <!-- in inches -->
<INPUT type="button" name="Submit" value="Run Analysis" onclick="subm(this.form,'/svg');"> <!-- svg so Firefox doesn't cache -->
<INPUT type="button" name="Submit" value="Get PDF of Plot" onclick="subm(this.form,'/pdf');"> </fieldset>
</form>
<form action="" method="POST" target="test" id="inputForm2">
<fieldset>
<legend><b>Select an Example Dataset</b></legend>
Dataset:
<select name="dataname">
<option value='"wilddogs"' selected >African Wilddogs</option>
<option value='"prairiechicken"'>Prairie Chickens</option>
<option value='"grouse"'>Sage Grouse</option>
<option value='"graywhales"'>Gray Whales</option>
</select></br />
<input name="!width" type="hidden" value=7 /> <!-- in inches -->
<input name="!height" type="hidden" value=6 /> <!-- in inches -->
<INPUT type="button" name="Submit" value="Run Analysis" onclick="subm2(this.form,'/svg');">
<INPUT type="button" name="Submit" value="Get PDF of Plot" onclick="subm2(this.form,'/pdf');">
</fieldset>
</form>
<fieldset class="references">
<legend><b>References</b></legend>
<p>Dennis, Brian, Patricia L. Munholland, and J. Michael Scott. "Estimation of growth and extinction parameters for endangered species." Ecological monographs 61.2 (1991): 115-143.</p>
<p>Holmes, E. E. 2001. Estimating risks in declining populations with poor data. Proceedings of the National Academy of Science 98: 5072-5077.</p>
</fieldset>
<fieldset class="references">
<legend><b>R Code</b></legend>
<!-- if you do not want to see the R code, use this <textarea hidden="hidden" id="RFunction" style="display:none;"> -->
<textarea id="RFunction" readonly="readonly" cols="27" rows="18" style="border:0px;margin:0px">
function(file=NULL, header=TRUE, dataname="wilddogs" ){
library(MARSS)
if(is.null(file)){
dat=get(dataname)
}else{
dat=read.csv(file, header=header)
dat=as.matrix(dat)
}
CSEGriskfigure(dat, silent=TRUE)
}
</textarea>
</fieldset>
<input type="hidden" value="not set" id="FunctionLocation" /> <!-- this is where the function is stored -->
<br />
</div>
<!-- This iframe holds the output image. -->
<iframe style='width: 7in; height: 6in; border: 0px solid #000000; padding: 10px;' name='test' id="image_iframe" class="rightCol"></iframe>
</div>
<!-- This is an onload script, but Chrome is not loading the whole page before running the onload script. Time out used above for this problem. -->
</body>
</html>
Upvotes: 1
Reputation: 32978
OpenCPU uses HTTP POST to execute functions, and HTTP GET to read/render objects and graphs. You could start with saving your function to the temporary store, and then calling it from there. A basic example is given in the "/R/tmp API" chapter of the interactive manual. If you click the red demo buttons named save a function
, get the function
and call the function
it will work you through the steps.
Basically in the first step you do a HTTP POST to the identity function to save your function in the store. This is also what is being done in the third form of the running code example page that you found. So I just copied your code there and then it returned me the object x0188b9b9ce
.
To inspect if everything went OK, you can then read this object using HTTP GET. For example, open this url to read the source code of your function:
http://public.opencpu.org/R/tmp/x0188b9b9ce/ascii
Alternative outputs are for example to get the function as an RData file:
http://public.opencpu.org/R/tmp/x0188b9b9ce/rda
Important is that HTTP GET never executes functions. It just looks stuff up, and returns it in the output format that you requested. So now that you're convinced your function is there in the store we want to run it. To do this you need a HTTP POST again. For example to obtain a PDF, you can do
POST http://public.opencpu.org/R/tmp/x0188b9b9ce/pdf
POST http://public.opencpu.org/R/tmp/x0188b9b9ce/svg
POST http://public.opencpu.org/R/tmp/x0188b9b9ce/png
If the function you calling takes arguments, you include them as parameters to the HTTP POST request. When you want to include the output in your webpage, usually you only want to use HTTP POST in combination with the /save
output type. So you would use jquery or whatever to do:
POST http://public.opencpu.org/R/tmp/x0188b9b9ce/save
Which might return something like this:
{
"object" : null,
"graphs" : [
"x2acba9501a"
],
"files" : {}
}
This indicates that your function has been executed successfully, and it created a plot (yay!). The graphic was saved to the tmp store. So you can now obtain the graphic and embed it in your page using HTTP GET:
http://public.opencpu.org/R/tmp/x2acba9501a/png
http://public.opencpu.org/R/tmp/x2acba9501a/png?!width=900&!height=500
http://public.opencpu.org/R/tmp/x2acba9501a/pdf
http://public.opencpu.org/R/tmp/x2acba9501a/svg
Upvotes: 3