-
Notifications
You must be signed in to change notification settings - Fork 0
/
jslib.html
494 lines (389 loc) · 25.9 KB
/
jslib.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
---
layout: page
title: "JavaScript Client"
description: The opencpu.js JavaScript Client Library documentation.
permalink: /jslib.html
---
<div class="row">
<div class="col-md-3">
<div id="docmenu" class="bs-sidebar hidden-print" data-spy="affix" data-offset-top="150" role="complementary">
<ul class="nav bs-sidenav">
<li>
<a class="active" href="#lib-library">About The Library</a>
<ul class="nav">
<li><a href="#lib-apps">OpenCPU Apps</a></li>
<li><a href="#lib-jquery">OpenCPU and jQuery</a></li>
<li><a href="#lib-cors">Cross Domain (CORS)</a></li>
<li><a href="#lib-jsfiddle">JSfiddle Examples</a></li>
</ul>
</li>
<li>
<a href="#lib-stateless">Stateless functions</a>
<ul class="nav">
<li><a href="#lib-plotwidget">Plotting Widget</a></li>
<li><a href="#lib-jsonrpc">Basic JSON RPC</a></li>
</ul>
</li>
<li>
<a href="#lib-callsandsessions">Calls and Sessions</a>
<ul class="nav">
<li><a href="#lib-sessions">State in OpenCPU</a></li>
<li><a href="#lib-function">Call a Function</a></li>
<li><a href="#lib-arguments">Argument Types</a></li>
<li><a href="#lib-session">Session Object</a></li>
</ul>
</li>
<!-- <li>
<a href="#lib-devel">Development Environment</a>
<ul class="nav">
<li><a href="#lib-singleuser">Single-user Server</a></li>
<li><a href="#lib-rstudio">Use in Rstudio</a></li>
</ul>
</li> -->
</ul>
</div>
</div>
<div class="col-md-9" role="main">
<div class="page-header">
<h1>CDN</h1>
</div>
<div class="row">
<div class="col-md-10 col-md-offset-1">
{% highlight html %}
<!-- OpenCPU client library -->
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="//cdn.opencpu.org/opencpu-0.4.js"></script>
{% endhighlight %}
</div>
</div>
<div class="page-header" id="lib-library">
<h1>About the Library</h1>
</div>
<p>The <a href="https://github.com/jeroenooms/opencpu.js">opencpu.js</a> JavaScript client library builds on <a target="_blank" href="http://jquery.com">jQuery</a> to provide Ajax wrappers for calling R from within a web page. The library works on all modern browsers, and lays the foundations for building scalable R web applications.</p>
<div class="panel panel-default" id="lib-apps">
<div class="panel-heading"><h4>Apps<small><em> — develop, ship and deploy standalone R web applications</em></small></h4></div>
<div class="panel-body">
<p>The opencpu.js library is primarly designed for developing apps. An app is an R package which includes web page(s) that call R functions in the package through the OpenCPU API. Thereby you can easily package, ship and deploy portable, standalone R web applications. A repository of public OpenCPU apps is available at <a href="http://github.com/opencpu" target="_blank">http://github.com/opencpu</a>. Because apps are simply R packages, they are installed just like any other R package:</p>
{% highlight r %}
#install apps: 'stocks', 'markdownapp' and 'nabel'
library(devtools)
install_github(c("stocks", "markdownapp", "nabel"), username="opencpu")
{% endhighlight %}
<p>By convention, the web pages are placed in the <code>/inst/www/</code> directory in the R package. To use an app locally, simply start the opencpu single-user server:</p>
{% highlight r %}
library(opencpu)
opencpu$browse("/library/stocks/www")
opencpu$browse("/library/nabel/www")
{% endhighlight %}
<p>The same apps can be installed and accessed on a cloud server by navigating to <code>/ocpu/library/[pkgname]/www/</code>:</p>
<ul>
<li><a href="https://cloud.opencpu.org/ocpu/library/stocks/www" target="_blank">https://cloud.opencpu.org/ocpu/library/stocks/www</a></li>
<li><a href="https://cloud.opencpu.org/ocpu/library/markdownapp/www" target="_blank">https://cloud.opencpu.org/ocpu/library/markdownapp/www</a></li>
<li><a href="https://cloud.opencpu.org/ocpu/library/nabel/www" target="_blank">https://cloud.opencpu.org/ocpu/library/nabel/www</a></li>
</ul>
<p>One app in the public repository is called <a href="https://cloud.opencpu.org/ocpu/library/appdemo/www">appdemo</a>. This application contains some minimal examples to demonstrate basic functionality and help you get started with building apps using <code>opencpu.js</code>.
</div>
</div>
<div class="panel panel-default" id="lib-jquery">
<div class="panel-heading"><h4>OpenCPU and jQuery<small><em> — loading the libraries</em></small></h4></div>
<div class="panel-body">
<p>The latest version of <code>opencpu.js</code> is available from github: <a href="https://github.com/jeroenooms/opencpu.js">https://github.com/jeroenooms/opencpu.js</a>. The jQuery library must be included in your web page <strong>before</strong> opencpu.js, because one depends on the other. Your application code must be included <strong>after</strong> opencpu.js.</p>
{% highlight html %}
<script src="js/jquery.js"></script>
<script src="js/opencpu.js"></script>
<script src="js/app.js"></script>
{% endhighlight %}
<p>It is recommended to ship a copy of the <code>opencpu.js</code> library with your application or website (as opposed to hotlinking it from some public location). This because the JavaScript library is in active development (0.x version) and the latest version might (radically) change from time to time. Shipping a version of <code>opencpu.js</code> with your app prevents it from breaking with upstream changes in the library. Also it is practical both for development and deployment if your app works offline.</p>
<p>Most functions in opencpu.js call out to <code>$.ajax</code> and return the <a href="http://api.jquery.com/jQuery.ajax/#jqXHR">jqXHR</a> object. Thereby you (the programmer) have full control over the request. Note that the A in Ajax stands for <strong>asynchronous</strong>, which means each ajax request returns immediately. Server responses are processed using <strong>callback functions</strong>. This paradigm can be a bit confusing to R users, but it results in flexible, non-blocking applications. If you are new to jQuery, at least familiarize yourself with the <code>jqXHR.done</code>, <code>jqXHR.fail</code> and <code>jqXHR.always</code> methods (see <a href="http://api.jquery.com/jQuery.ajax/#jqXHR">jqXHR</a>). </p>
</div>
</div>
<div class="panel panel-default" id="lib-cors">
<div class="panel-heading"><h4>CORS<small><em> — cross-domain opencpu requests</em></small></h4></div>
<div class="panel-body">
<p>The recommended design for OpenCPU apps is to include the web pages in the R package. This results in a standalone application, which is easy to distribute and deploy and can also be used offline. Furthermore, it guarantees that the version of front-end and R code are in sync, and the package manager automatically takes care of dependencies when the app is installed on a server. </p>
<p>However it is also possible to use the <code>opencpu.js</code> library from an external site that is not hosted on OpenCPU. In this case, we must specify the external OpenCPU server using <code>ocpu.seturl()</code>:</p>
{% highlight js %}
//set page to communicate to with "mypackage" on server below
ocpu.seturl("//cloud.opencpu.org/ocpu/library/mypackage/R")
{% endhighlight %}
<p>Cross domain requests are convenient for development and illustrative examples, see e.g: <a href="http://jsfiddle.net/user/opencpu/fiddles/">jsfiddle examples</a>. However, when possible it is still recommended to include a copy of your web pages in the R package for every release of your app. That way you get a nice redistributable app and there is no ambiguity over version compatibility of the front-end (web pages) and back-end (R functions). </p>
<p>Also note that even when using CORS, the <code>opencpu.js</code> library still requires that all R functions used by a certain application are contained in a single R package. This is on purpose, to force you to keep things organized. If you would like to use functionality from various R packages, you need to create an R package that includes some wrapper functions and formally declares its dependencies on the other packages. Writing an R package is really easy these days, so this should be no problem. </p>
</div>
</div>
<div class="panel panel-default" id="lib-jsfiddle">
<div class="panel-heading"><h4>JSfiddle<small><em> — fiddle around with some examples</em></small></h4></div>
<div class="panel-body">
Since OpenCPU now supports CORS, and so do all major browsers, we started using JSfiddle to illustrate how to use the library. The <a href="http://jsfiddle.net/user/opencpu/fiddles/">opencpu jsfiddle</a> homepage lists all our fiddles, and we will keep adding new examples. Many of these examples are actually referenced and explained in this manual page. But if this is all tl;dr, just <a href="http://jsfiddle.net/user/opencpu/fiddles/">start playing</a>.</p>
</div>
</div>
<div class="page-header" id="lib-stateless">
<h1>Stateless functions</h1>
</div>
<p>This chapter describes two high-level functions that are used to call R functions that generate either a plot or return some data. They are easy to use because they directly take the output from the R function; no session management is required.</p>
<div class="panel panel-default" id="lib-plotwidget">
<!-- Default panel contents -->
<div class="panel-heading"><h4>The Plot Widget <small><em> — generate an R plot in a div</em></small></h4></div>
<div class="panel-body">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"><tt>$("#mydiv").rplot( fun, [, args ] [, callback ]) <span class="pull-right">Returns: <a target="_blank" href="http://api.jquery.com/jQuery.ajax/#jqXHR"><code>jqXHR</code></a></span> </tt></h3>
</div>
<div class="panel-body">
<strong>fun</strong> <tt>(string)</tt> <br>Name of the R function <em>(required)</em> <hr>
<strong>args</strong> <tt>(object)</tt> <br>Function arguments. <hr>
<strong>callback</strong> <tt>(function)</tt> <br>Callback function. Not needed for plot widget. Called with session object.
</div>
</div>
<p>A fun an easy way to get started is by making plots. The <code>opencpu.js</code> library implements a jquery plugin called <code>rplot</code> which makes it easy to embed live plots in your webpage. For example, consider the R function <a href="http://cloud.opencpu.org/ocpu/library/stocks/R/smoothplot">smoothplot</a> in the <a href="http://github.com/opencpu/stocks">stocks package</a>:</p>
{% highlight r%}
#The R function
function(ticker = "GOOG", from = "2013-01-01", to=Sys.time()){
mydata <- yahoodata(ticker, from, to);
qplot(Date, Close, data = mydata, geom = c("line", "smooth"));
}
{% endhighlight %}
<p>It defines three arguments, each of which optional: <code>ticker</code>, <code>from</code>, and <code>to</code>. These are the arguments that we can pass from the <code>opencpu.js</code> client app. In this example, we only pass the first two arguments.</p>
{% highlight js%}
//JavaScript client code
var ticker = $("#ticker").val();
var req = $("#plotdiv").rplot("smoothplot", {
ticker : ticker,
from : "2013-01-01"
})
//optional: add custom callbacks
req.fail(function(){
alert("R returned an error: " + req.responseText);
});
{% endhighlight %}
<p>This creates a plot widget in the <code>#plotdiv</code> element (a div in your html). It calls the R function <code>smoothplot</code> and passes argument values as specified, and displays the generated plot including PNG, PDF, and SVG export links. The final lines specify an error handler, which is optional but recommended. Have a look at the <a href="http://jsfiddle.net/opencpu/MkAVF/">jsfiddle</a>, or the full <a href="https://cloud.opencpu.org/ocpu/library/stocks/www/">stocks app</a> to see all of this in action!</p>
</div>
</div>
<div class="panel panel-default" id="lib-jsonrpc">
<!-- Default panel contents -->
<div class="panel-heading"><h4>Basic JSON RPC <small><em> — a.k.a Data Processing Unit</em></small></h4></div>
<div class="panel-body">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"><tt>ocpu.rpc( fun, [, args ] [, complete ] ) <span class="pull-right">Returns: <a target="_blank" href="http://api.jquery.com/jQuery.ajax/#jqXHR"><code>jqXHR</code></a></span> </tt></h3>
</div>
<div class="panel-body">
<strong>fun</strong> <tt>(string)</tt> <br>Name of the R function <em>(required)</em> <hr>
<strong>args</strong> <tt>(object)</tt> <br>Function arguments. <hr>
<strong>complete</strong> <tt>(function)</tt> <br>Callback function. Is called only on success with one arg: R function return value.
</div>
</div>
<p>With opencpu.js we can use R as a remote calculator. Consider the very simple example of calculating the standard deviation for a vector of numbers. In this case we call the default R function sd in the stats package</p>
{% highlight js%}
var mydata = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
//call R function: stats::sd(x=data)
var req = ocpu.rpc("sd",{
x : mydata
}, function(output){
alert("Standard Deviation equals: " + output);
});
//optional
req.fail(function(){
alert("R returned an error: " + req.responseText);
});
{% endhighlight %}
<p>See it in action <a href="http://jsfiddle.net/opencpu/T3cqH/">here</a>. When calling <code>ocpu.rpc</code>, the arguments as well as return value are transferred using JSON. On the R side, the <code>jsonlite</code> package is used to convert between JSON and R objects. Hence, the above code is equivalent to the R code below. The <code>output</code> object is a JSON string which is sent back to the client and parsed by JavaScript.</p>
{% highlight r%}
library(jsonlite)
#parse input from JSON into R
jsoninput <- '{"x" : [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]}'
fnargs <- fromJSON(jsoninput)
#the actual function call
result <- do.call(stats::sd, fnargs)
#convert result back to JSON
jsonoutput <- toJSON(result)
{% endhighlight %}
<p>Another example is available here: <a href="http://jsfiddle.net/opencpu/9nVd5/">http://jsfiddle.net/opencpu/9nVd5/</a>. This example calls the <code>lowess</code> function in R, to smooth a bunch of values. This can be useful to remove outliers from noisy data. One difference with the previous example, is that <code>lowess</code> does not return a single value, but a list with two vectors: <code>x</code> and <code>y</code>. See the lowess help page for more detail.</p>
</div>
</div>
<div class="page-header" id="lib-callsandsessions">
<h1>Calls and Sessions</h1>
</div>
<p>The stateless functions are convenient for applications with a single R function call and a single output (either a plot or the function return value). However, other applications might require more sophisticated interaction with the R session. This section section talks about stateful applications; i.e. the client creates and manipulates objects on the server. Therefore, the difference with before is that calling functions (POST) is decoupled from retrieving output (GET).</p>
<div class="panel panel-default" id="lib-sessions">
<!-- Default panel contents -->
<div class="panel-heading"><h4>State in OpenCPU<small><em> — managing sessions</em></small></h4></div>
<div class="panel-body">
<p>Management of state in OpenCPU is quite different from what R users are used to, which can be confusing at first. In OpenCPU, the client does <strong>not</strong> have a single private R process on the server which handles all incoming requests, such as in e.g. Shiny or in an R terminal session. Instead, OpenCPU is plain HTTP, and therefore each requests is anonymous and <em>stateless</em>. After every function call, OpenCPU cleans (or kills) the R process that was used to handle the request. </p>
<p> However, all outputs of every function call, such as return value, graphics, stdout or files in working directory, are stored on the server, and a <strong>session ID</strong> is returned to the client. These session IDs can be used to control these outputs on the server in future requests. For example, a client can retrieve outputs in various formats, share them with others, or use stored R objects as arguments in subsequent function calls. Hence to build a <em>statefull</em> application, there is no point in assigning objects to the global environment. Instead, we need to design R functions to return the value of interest. This way the client can call the function, and use its return value in subsequent function calls. </p>
<p>This design has several advantages that are important for scalable applications:</p>
<ul>
<li>Non blocking: everything is async, your GUI won't block while waiting for R to return.</li>
<li>Robustness: if an R call gets stuck, errors or crashes, it doesn't take down your application.</li>
<li>Concurrency: applications are parallel by design. Clients can perform simultaneous requests and combine results later.</li>
</ul>
</div>
</div>
<div class="panel panel-default" id="lib-function">
<!-- Default panel contents -->
<div class="panel-heading"><h4>Call an R function <small><em> — decouple call from output</em></small></h4></div>
<div class="panel-body">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"><tt>ocpu.call( fun, [, args ] [, callback ] ) <span class="pull-right">Returns: <a target="_blank" href="http://api.jquery.com/jQuery.ajax/#jqXHR"><code>jqXHR</code></a></span> </tt></h3>
</div>
<div class="panel-body">
<strong>fun</strong> <tt>(string)</tt> <br>Name of the R function <em>(required)</em> <hr>
<strong>args</strong> <tt>(object)</tt> <br>Function arguments. <hr>
<strong>callback</strong> <tt>(function)</tt> <br>Callback function. 1 argument: Session object.
</div>
</div>
<p>The <code>ocpu.call</code> function is the stateful equivalent of <code>ocpu.rpc</code>. It has the same arguments, but the difference is in the callback function. The <code>ocpu.rpc</code> callback argument is a JSON object containing the data returned by the R function. The <code>ocpu.call</code> callback argument is a <em>Session object</em>. The session object is a javascript class that stores the session ID; it does not contain any actual data. However, from the session object, we can asynchronously retrieve data, plots, files, stdout, etc. See <a href="http://jsfiddle.net/opencpu/tmqab/">this jsfiddle</a> in action.</p>
{% highlight js%}
//toy example
var req = ocpu.call("rnorm", {n: 100}, function(session){
//read the session properties (just for fun)
$("#key").text(session.getKey());
$("#location").text(session.getLoc());
//retrieve session console (stdout) async
session.getConsole(function(outtxt){
$("#output").text(outtxt);
});
//retrieve the returned object async
session.getObject(function(data){
//data is the object returned by the R function
alert("Array of length " + data.length + ".\nFirst few values:" + data.slice(0,3));
});
})
{% endhighlight %}
<p>We can also use the Session object to pass the R value returned by the function call as an argument to a subsequent function call, without ever retrieving the object. All state in OpenCPU is managed by controlling R objects in sessions on the server. This <a href="http://jsfiddle.net/opencpu/ecwbd/">jsfiddle example</a> continues on the previous example, and calculates the variance of the vector generated before, by passing the session object as an argument. A more simple example <a href="http://jsfiddle.net/opencpu/mH52T/">here</a></p>
{% highlight js%}
var req1 = ocpu.call("rnorm", {n: 100}, function(session1){
var req2 = ocpu.call("var", {x : session1}, function(session2){
session2.getObject(function(data){
alert("Variance equals: " + data);
});
});
});
{% endhighlight %}
</div>
</div>
<div class="panel panel-default" id="lib-arguments">
<!-- Default panel contents -->
<div class="panel-heading"><h4>Argument Types <small><em> — passing data to opencpu</em></small></h4></div>
<div class="panel-body">
<p>In <code>opencpu.js</code> there are 4 types of arguments: a basic JavaScript value/object (automatically converted to R via JSON), a session object (represents an R value from a previous function call), a file and a code snippet. We have already seen examples the first two argument types earlier. Below is an example of using a file as an argument. The file will automatically be uploaded and used to call the R function. See it in action using <a href="http://jsfiddle.net/opencpu/5Rqcm/">this jsfiddle</a>.</p>
{% highlight js %}
//This must be HTML5 <input type="file">
var myfile = $("#csvfile")[0].files[0];
var header = true;
//call read.csv in R. File is automatically uploaded
var req = ocpu.call("read.csv", {
"file" : myfile,
"header" : myheader
}, function(session){
//use output here
});
{% endhighlight %}
<p>The final type of argument is a code snippet. This injects raw R code into the function call. It is usually recommended to use this type only when really needed, because it requires the client to understand R code, which kills interoperability. But this argument type is useful for example in applications that explicitly let the user do some R coding. See <a href="http://jsfiddle.net/opencpu/4dgdM/">here</a> for a basic example: </p>
{% highlight js %}
//create snippet argument
var x = new ocpu.Snippet($("#input").val());
//perform the request
var req = ocpu.call("mean", {
"x" : x
}, function(session){
//use output here
});
{% endhighlight %}
<p>One interesting special case is using a code Snippet when calling the <code>identity</code> function in R. This comes down to executing a raw block of code in a session. Try <a href="http://jsfiddle.net/opencpu/v42v3/">this jsfiddle</a> to see this in action.</p>
</div>
</div>
<div class="panel panel-default" id="lib-session">
<!-- Default panel contents -->
<div class="panel-heading"><h4>The Session Object <small><em> — controlling objects, plots, files, etc</em></small></h4></div>
<div class="panel-body">
<p>The callback argument for <code>ocpu.call()</code> is always a session object. This object does not contain actual data, it just holds a sessoin ID and which can be used to retrieve output from the server. All session objects have the following methods:</p>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"><tt>session.getKey() <span class="pull-right">Returns: string</span> </tt></h3>
</div>
<div class="panel-body">
Read the session ID. For debugging only.
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"><tt>session.getLoc() <span class="pull-right">Returns: string</span> </tt></h3>
</div>
<div class="panel-body">
Read the session URL. For debugging only.
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"><tt>session.getFileURL( path ) <span class="pull-right">Returns: string</span> </tt></h3>
</div>
<div class="panel-body">
<strong>path</strong> <tt>(string)</tt> <br>Path of the file w.r.t. working directory. <em>(required)</em>
</div>
</div>
<p>The methods below initiate an ajax request and return the jqXHR object. A callback is required to process output.</p>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"><tt>session.getObject( [ name ] [, data ] [, success ]) <span class="pull-right">Returns: jqXHR</span> </tt></h3>
</div>
<div class="panel-body">
<strong>name</strong> <tt>(string)</tt> <br>Name of the object. Usually not required. Defaults to .val which means the function return value. <hr>
<strong>data</strong> <tt>(object)</tt> <br>Arguments for the /json output format. <hr>
<strong>success</strong> <tt>(function)</tt> <br>Callback argument: function return data.
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"><tt>session.getConsole( [ success ] ) <span class="pull-right">Returns: jqXHR</span> </tt></h3>
</div>
<div class="panel-body">
<strong>success</strong> <tt>(function)</tt> <br>Callback argument: session console text.
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"><tt>session.getStdout( [ success ] ) <span class="pull-right">Returns: jqXHR</span> </tt></h3>
</div>
<div class="panel-body">
<strong>success</strong> <tt>(function)</tt> <br>Callback argument: session stdout text.
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"><tt>session.getFile( path [, success ] ) <span class="pull-right">Returns: jqXHR</span> </tt></h3>
</div>
<div class="panel-body">
<strong>path</strong> <tt>(string)</tt> <br>Path of the file w.r.t. working directory. <em>(required)</em> <hr>
<strong>success</strong> <tt>(function)</tt> <br>Callback argument: file content.
</div>
</div>
</div>
</div>
<!--spacer-->
<div style="height:500px;"></div>
</div>
</div>
<script>
$(function(){
$('body').scrollspy({ target: '#docmenu', offset:80 })
});
//fancy scrolling animation
if(!(/iPhone|iPod|iPad|Android|BlackBerry/).test(navigator.userAgent)){
$("#docmenu li a").on('click', function(e) {
// prevent default anchor click behavior
e.preventDefault();
$(this).blur();
// store hash
var hash = this.hash;
// animate
$('html, body').animate({
scrollTop: $(this.hash).offset().top - 65
}, 500, function(){
// when done, add hash to url
// (default click behaviour)
window.location.hash = hash;
});
});
}
</script>