<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PiCloud Blog &#187; new features</title>
	<atom:link href="http://blog.picloud.com/tag/new-features/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.picloud.com</link>
	<description>Cloud Computing. Simplified.</description>
	<lastBuildDate>Wed, 25 Jan 2012 01:15:07 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Introducing Scraping-Optimized Cores</title>
		<link>http://blog.picloud.com/2011/10/10/introducing-scraping-optimized-cores/</link>
		<comments>http://blog.picloud.com/2011/10/10/introducing-scraping-optimized-cores/#comments</comments>
		<pubDate>Mon, 10 Oct 2011 22:01:29 +0000</pubDate>
		<dc:creator>Ken Elkabany</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[new features]]></category>
		<category><![CDATA[s1]]></category>
		<category><![CDATA[scraping]]></category>

		<guid isPermaLink="false">http://blog.picloud.com/?p=690</guid>
		<description><![CDATA[
For users who aggregate data from around the web, you&#8217;ll find our latest core to be an integral part of your toolbox. s1 cores are comparable in performance to c1 cores with one extra trick up their sleeve: each job running in parallel will have a different IP.

Why is this important?

Using unique IPs is necessary [...]]]></description>
			<content:encoded><![CDATA[<p>
For users who aggregate data from around the web, you&#8217;ll find our latest core to be an integral part of your toolbox. <b>s1</b> cores are comparable in performance to <b>c1</b> cores with one extra trick up their sleeve: each job running in parallel will have a different IP.
</p>
<h3>Why is this important?</h3>
<p>
Using unique IPs is necessary to minimize the automated throttling most sites will impose when seeing fast, repeated access from a single IP.
</p>
<h3>How do I use it?</h3>
<p>
If you&#8217;re already using our <b>c1</b> cores, all you&#8217;ll need to do is set the <code>_type</code> keyword.
</p>
<p class="code" style="font-size:13px; color:#202020">
<font face="Courier New">cloud.call(func, _type=&#8217;s1&#8242;)</font>
</p>
<h3>How much?</h3>
<p>
$0.04/core/hour
</p>
<h3>Why don&#8217;t other cores have individual IPs?</h3>
<p>
For other core types, such as <b>c2</b>, multiple cores may be running on a single machine that is assigned only a single IP address. When using <b>s1</b> cores, you&#8217;re guaranteed that each core sits on a different machine.
</p>
<h3>Suggestions?</h3>
<p>
We&#8217;re excited to move the <b>s1</b> core type out of beta for our customers. If you have any suggestions for other core types you would like to see, please let us know.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.picloud.com/2011/10/10/introducing-scraping-optimized-cores/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing Environments &#8212; Run Anything on PiCloud</title>
		<link>http://blog.picloud.com/2011/09/26/introducing-environments-run-anything-on-picloud/</link>
		<comments>http://blog.picloud.com/2011/09/26/introducing-environments-run-anything-on-picloud/#comments</comments>
		<pubDate>Mon, 26 Sep 2011 23:45:47 +0000</pubDate>
		<dc:creator>Ken Elkabany</dc:creator>
				<category><![CDATA[What's New]]></category>
		<category><![CDATA[environment]]></category>
		<category><![CDATA[new features]]></category>

		<guid isPermaLink="false">http://blog.picloud.com/?p=511</guid>
		<description><![CDATA[
Environments mark an important milestone for PiCloud. Whereas Function Publishing makes the computing power of PiCloud accessible to all programming languages, Environments enable you to use any library or binary you need in your computation. The possibilities are limitless, but here are a couple examples of what you can do with environments:



Install any non-Python software [...]]]></description>
			<content:encoded><![CDATA[<p>
Environments mark an important milestone for PiCloud. Whereas <a href="http://blog.picloud.com/2011/09/14/introducing-function-publishing-via-rest/">Function Publishing</a> makes the computing power of PiCloud accessible to all programming languages, Environments enable you to use <b>any</b> library or binary you need in your computation. The possibilities are limitless, but here are a couple examples of what you can do with environments:
</p>
<p></p>
<ol>
<li>Install any non-Python software package you need via apt-get or make.</li>
<li>Install any Python module that we do not automatically extract from your machines, which are typically those that require compilation or depend on external libraries.</li>
</ol>
<p>In this post, we&#8217;ll show you how to create and use your first environment. We&#8217;ll be installing the <a href="http://obspy.org/">ObsPy</a> package, which is a Python toolbox for processing seismological data.</p>
<h3>Why Environments?</h3>
<p>
We strive to make moving your computation to the cloud as easy as possible. That&#8217;s why our <code>cloud</code> Python package automatically detects and transfers dependencies over to our cloud.
</p>
<pre class="brush: python; title: ; notranslate">
import cloud
from your_expansive_library_of_functions import complex_function
# cloud.call transfers all the modules needed to run complex_function on PiCloud
cloud.call(complex_function)
</pre>
<p>
Unfortunately, automatic dependency transfer only works for pure Python modules. The <code>ObsPy</code> package requires both a .pth file and C-code compilation for proper operation. So the following simple function quickly runs into problems:
</p>
<pre class="brush: python; title: ; notranslate">
def simple_function():
    import obspy
</pre>
<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; jid = cloud.call(simple_function)
&gt;&gt;&gt; cloud.result(jid)
[Mon Sep 19 16:39:13 2011] - [WARNING] - Cloud: Job 1337 threw exception:
 Could not depickle job
Traceback (most recent call last):
  File &quot;/usr/local/lib/python2.7/dist-packages/cloud/serialization/cloudpickle.py&quot;, line 679, in subimport
    __import__(name)
ImportError: No module named obspy
</pre>
<p>
Importing <code>ObsPy</code> fails because it could not be transferred to PiCloud in working form. You might be wondering how you&#8217;ve been able to use NumPy, SciPy, and other natively-compiled libraries on PiCloud. The answer is we have many libraries pre-installed on our systems. Here are the respective links for what we have pre-installed for <a href="http://www.picloud.com/docs/base_environment/1/installed/">Python 2.6</a>, and <a href="http://www.picloud.com/docs/base_environment/2/installed/">Python 2.7</a>.
</p>
<h3>Creating a new Environment</h3>
<p>
<b>Step 1: Go to the Environments tab in the Control Panel.</b>
</p>
<p><a href="http://media.picloud.com/img/blog/environment_blank_ui_panel.png"><br />
<img src="http://media.picloud.com/img/blog/environment_blank_ui_panel.png" /><br />
</a></p>
<p></p>
<p>
<b>Step 2: Click &#8220;create new environment&#8221;.</b>
</p>
<p><a href="http://media.picloud.com/img/blog/environment_create_ui_panel.png"><br />
<img src="http://media.picloud.com/img/blog/environment_create_ui_panel.png" style="width: 90%; display: block; margin-left: auto; margin-right: auto; border: 2px solid #ccc;" /><br />
</a></p>
<p>
A popup box will appear. The <i>Base Environment</i> option allows you to choose what distribution of <a href="http://www.ubuntu.com">Ubuntu Linux</a> you would like to use as the base filesystem. It&#8217;s important to understand why we give you this option. If you use Python 2.7 on your local machine to offload computation to PiCloud, we will run your functions in the Python 2.7 interpreter from the Ubuntu 11.04 (Natty) base. If you use Python 2.6 on your local machine to offload computation to PiCloud, we will run your functions in the Python 2.6 interpreter from the Ubuntu 10.10 (Maverick) base. We are consistent about which interpreter we use since the modules you install in your environment may compile against a specific version of Python. In short, if you&#8217;re using Python 2.6 on your machines, but you use the Natty base, or vice versa, you will most likely run into compatibility issues.
</p>
<p>
The <i>Environment Name</i> is the name you&#8217;ll use to reference the environment in your jobs. The <i>Environment Description</i> is for yourself and/or your team to keep track of the purpose and contents of each environment.
</p>
<p></p>
<p>
<b>Step 3: Click submit.</b>
</p>
<p>
When you click submit, your environment will appear under the &#8220;Environments being configured&#8221; tab. You may have to wait a minute or two while we boot and configure a server with the appropriate base environment for you.
</p>
<p><img src="http://media.picloud.com/img/blog/environment_setup_ui_panel.png" /></p>
<p>
For our example, we&#8217;ve named the environment <b>seismology_env</b>.
</p>
<h3>Connecting to your Environment Setup Server</h3>
<p>
When the server is ready, click the connect link. Note that the instructions are currently tailored towards *nix environments. If you are using Windows and do not have an SSH client, we recommend <a href="http://www.bitvise.com/tunnelier">Tunnelier</a>.
</p>
<p><a href="http://media.picloud.com/img/blog/environment_connect_ui_panel.png"><br />
<img src="http://media.picloud.com/img/blog/environment_connect_ui_panel.png" style="width: 90%; display: block; margin-left: auto; margin-right: auto; border: 2px solid #ccc;" /><br />
</a></p>
<p>
Download the private key we have generated for you. You will use this same private key for all future environment setup servers. SSH enforces that only the owner should have access to the file, which is why we instruct you to run <code>chmod 400 privatekey.pem</code>. Once you&#8217;ve done that, SSH into the provided server using the private key by using the <code>-i</code> flag as shown in the instructions.
</p>
<h3>Getting Around Your Environment</h3>
<p>Once you&#8217;ve SSH-ed in, you&#8217;ll find yourself in a Ubuntu Linux filesystem environment.</p>
<pre class="brush: bash; title: ; notranslate">
picloud@ip-10-46-223-4:~$ ls /
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  sbin  selinux  srv  sys  tmp  usr  var
</pre>
<p>
Your current working directory is <code>/home/picloud</code>:
</p>
<pre class="brush: bash; title: ; notranslate">
picloud@ip-10-46-223-4:~$ pwd
/home/picloud
</pre>
<p>
You can verify the distribution of Ubuntu you&#8217;re using:
</p>
<pre class="brush: bash; title: ; notranslate">
picloud@ip-10-46-223-4:~$ cat /etc/issue
Ubuntu 11.04 \n \l
</pre>
<p>
We give you sudo access so that you have the freedom to install anything anywhere.
</p>
<pre class="brush: bash; title: ; notranslate">
# this does not produce an error
picloud@ip-10-46-223-4:~$ sudo touch /root/i_can_be_root
</pre>
<p>
<b>Important</b>: The owner and group for files and directories in your environment do not matter. While you&#8217;ll be using the <code>setup</code> and <code>root</code> user accounts, your jobs will be run with an entirely different user account that will have access to the entire filesystem environment.
</p>
<h3>Setting Up Your Environment</h3>
<p>
We&#8217;ll use <code>sudo</code> access to install the ObsPy library.
</p>
<pre class="brush: bash; title: ; notranslate">
picloud@ip-10-46-223-4:~$ sudo pip install obspy.core obspy.signal
Downloading/unpacking obspy.core
  Downloading obspy.core-0.4.8.zip (186Kb): 186Kb downloaded
  Running setup.py egg_info for package obspy.core

    no previously-included directories found matching 'docs/other/*'
Downloading/unpacking obspy.signal
  Downloading obspy.signal-0.4.9.zip (4.0Mb): 4.0Mb downloaded
  Running setup.py egg_info for package obspy.signal

Requirement already satisfied (use --upgrade to upgrade): numpy&gt;1.0.0 in /usr/local/lib/python2.7/dist-packages (from obspy.core)
Requirement already satisfied (use --upgrade to upgrade): scipy in /usr/local/lib/python2.7/dist-packages (from obspy.signal)
Installing collected packages: obspy.core, obspy.signal
  Running setup.py install for obspy.core

    no previously-included directories found matching 'docs/other/*'
    Skipping installation of /usr/local/lib/python2.7/dist-packages/obspy/__init__.py (namespace package)
    Installing /usr/local/lib/python2.7/dist-packages/obspy.core-0.4.8-nspkg.pth
    Installing obspy-runtests script to /usr/local/bin
  Running setup.py install for obspy.signal

    building 'libsignal' extension
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/local/lib/python2.7/dist-packages/numpy/core/include -I/usr/include/python2.7 -c obspy/signal/src/recstalta.c -o build/temp.linux-x86_64-2.7/obspy/signal/src/recstalta.o
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/local/lib/python2.7/dist-packages/numpy/core/include -I/usr/include/python2.7 -c obspy/signal/src/xcorr.c -o build/temp.linux-x86_64-2.7/obspy/signal/src/xcorr.o
    ...
I/usr/include/python2.7 -c obspy/signal/src/fft/fftpack_litemodule.c -o build/temp.linux-x86_64-2.7/obspy/signal/src/fft/fftpack_litemodule.o
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.7/obspy/signal/src/recstalta.o build/temp.linux-x86_64-2.7/obspy/signal/src/xcorr.o build/temp.linux-x86_64-2.7/obspy/signal/src/coordtrans.o build/temp.linux-x86_64-2.7/obspy/signal/src/pk_mbaer.o build/temp.linux-x86_64-2.7/obspy/signal/src/filt_util.o build/temp.linux-x86_64-2.7/obspy/signal/src/arpicker.o build/temp.linux-x86_64-2.7/obspy/signal/src/bbfk.o build/temp.linux-x86_64-2.7/obspy/signal/src/fft/fftpack.o build/temp.linux-x86_64-2.7/obspy/signal/src/fft/fftpack_litemodule.o -o build/lib.linux-x86_64-2.7/obspy/signal/lib/libsignal.so
    Skipping installation of /usr/local/lib/python2.7/dist-packages/obspy/__init__.py (namespace package)
    Installing /usr/local/lib/python2.7/dist-packages/obspy.signal-0.4.9-nspkg.pth
Successfully installed obspy.core obspy.signal
Cleaning up...
</pre>
<p>
As you can see, installing <code>obspy.signal</code> requires compiling C code with references to the NumPy library. We would not have been able to automatically extract this package from your machine.
</p>
<h3>Save the Environment</h3>
<p>
When you click &#8220;save&#8221; from the Environment Panel, your SSH connection will be closed. The length of time it takes to save your environment depends on how much you&#8217;ve installed. Once it&#8217;s ready, your new Environment will be listed under the &#8220;Your environments&#8221; section.
</p>
<h3>Using Your Environment</h3>
<p>
To use an environment, use the <code>_env</code> keyword argument to specify the environment you want to use by name. <code>_env</code> is valid for <code>cloud.call</code>, <code>cloud.map</code>, <code>cloud.cron.register</code>, or <code>cloud.rest.publish</code>.
</p>
<p>
To demonstrate, we will run a beamforming algorithm using the ObsPy library that we just installed. Beamforming is a technique used in seismology for geolocating seismic events. In this case, the event is the <a href="http://www.youtube.com/watch?v=oolfRoxta-E">demolition of the AGFA skyscraper in Munich</a>. We&#8217;ve derived the example from <a href="http://docs.obspy.org/tutorial/beamforming-fk-analysis.html">here</a>.
</p>
<p></p>
<p>
<b>Step 1: Upload the recorded <a href="http://examples.obspy.org/agfa.dump">dataset from the demolition</a> to <code>cloud.files</code></b>
</p>
<pre class="brush: python; title: ; notranslate">
cloud.files.put('agfa.dump')
</pre>
<p></p>
<p>
<b>Step 2: Define the beamforming function.</b>
</p>
<p>
Note that our version pulls the data from <code>cloud.files</code> directly into memory using the <code>getf</code> function.
</p>
<pre class="brush: python; title: ; notranslate">
import cloud
import pickle, urllib
from obspy.core import UTCDateTime
from obspy.signal.array_analysis import sonic
from obspy.signal import cornFreq2Paz

def beamforming(file_name):
    st = pickle.loads(cloud.files.getf(file_name).read())

    # Instrument correction to 1Hz corner frequency
    paz1hz = cornFreq2Paz(1.0, damp=0.707)
    st.simulate(paz_remove='self', paz_simulate=paz1hz)

    # Execute sonic
    kwargs = dict(
	# slowness grid: X min, X max, Y min, Y max, Slow Step
	sll_x=-3.0, slm_x=3.0, sll_y=-3.0, slm_y=3.0, sl_s=0.03,
	# sliding window propertieds
	win_len=1.0, win_frac=0.05,
	# frequency properties
	frqlow=1.0, frqhigh=8.0, prewhiten=0,
	# restrict output
	semb_thres=-1e9, vel_thres=-1e9, verbose=True, timestamp='mlabhour',
	stime=UTCDateTime(&quot;20080217110515&quot;), etime=UTCDateTime(&quot;20080217110545&quot;)
    )

    return sonic(st, **kwargs)
</pre>
<p></p>
<p>
<b>Step 3: Run it on PiCloud using the <code>_env</code> keyword.</b>
</p>
<p>
Since this is a computationally intensive task, we use the <b>c2</b> core type to take advantage of 2.5 compute units of power.
</p>
<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; jid = cloud.call(beamforming, 'agfa.dump', _env='seismology_env', _type='c2')
&gt;&gt;&gt; out = cloud.result(jid)
&gt;&gt;&gt; out
array([[  7.33088462e+05,   6.52313948e-01,   4.77909058e-17,
          1.63009177e+02,   1.12929181e+00],
       [  7.33088462e+05,   6.54728115e-01,   4.92721051e-17,
          1.58838740e+02,   9.97246208e-01],
       [  7.33088462e+05,   6.65887892e-01,   5.40099541e-17,
          1.58552264e+02,   9.02496537e-01],
       ...,
       [  7.33088462e+05,   7.97200561e-01,   2.54941247e-16,
          1.84349488e+01,   1.23328829e+00],
       [  7.33088462e+05,   7.93642402e-01,   2.90117096e-16,
         -1.20947571e+01,   8.59069264e-01],
       [  7.33088462e+05,   8.08987796e-01,   3.06803433e-16,
         -2.65650512e+01,   8.72066511e-01]])
</pre>
<p>
To better visualize the result, we can plot the output:
</p>
<p><a href="http://media.picloud.com/img/blog/environment_beamforming_output.png"><br />
<img src="http://media.picloud.com/img/blog/environment_beamforming_output.png" style="width: 100%; display: block; margin-left: auto; margin-right: auto;" /><br />
</a></p>
<p>
The following code was used to generate the plot:
</p>
<pre class="brush: python; title: ; notranslate">
import matplotlib.pyplot as plt
labels = 'rel.power abs.power baz slow'.split()

fig = plt.figure()
for i, lab in enumerate(labels):
    ax = fig.add_subplot(4, 1, i + 1)
    ax.scatter(out[:, 0], out[:, i + 1], c=out[:, 1], alpha=0.6,
               edgecolors='none')
    ax.set_ylabel(lab)
    ax.xaxis_date()

fig.autofmt_xdate()
fig.subplots_adjust(top=0.95, right=0.95, bottom=0.2, hspace=0)
</pre>
<h3>Pricing</h3>
<p>
Creating environments is <b>free</b>. There are no additional charges associated with this feature. From our perspective, environments allow you to run more cycles on PiCloud, which is where we get our pay off.
</p>
<h3>Conclusion</h3>
<p>
With Environments, every programming language and software package is now a viable tool to use on PiCloud. While we love Python, we&#8217;re excited that it is no longer the &#8220;sole language of the PiCloud Platform.&#8221; Coupled with our function publishing feature, we envision Python serving as the glue language through which users can orchestrate their computation on our otherwise language-agnotistic platform.
</p>
<p><a href="http://media.picloud.com/img/blog/language_agnostic_features.png"><br />
<img src="http://media.picloud.com/img/blog/language_agnostic_features.png" style="width: 100%; display: block; margin-left: auto; margin-right: auto;" /><br />
</a></p>
<p>
Thanks to the select group of users who beta tested this feature for us, and to Ken Park from PiCloud who envisioned and shepherded this project to launch!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.picloud.com/2011/09/26/introducing-environments-run-anything-on-picloud/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Introducing Function Publishing via REST</title>
		<link>http://blog.picloud.com/2011/09/14/introducing-function-publishing-via-rest/</link>
		<comments>http://blog.picloud.com/2011/09/14/introducing-function-publishing-via-rest/#comments</comments>
		<pubDate>Thu, 15 Sep 2011 01:57:50 +0000</pubDate>
		<dc:creator>Ken Elkabany</dc:creator>
				<category><![CDATA[What's New]]></category>
		<category><![CDATA[function publishing]]></category>
		<category><![CDATA[new features]]></category>
		<category><![CDATA[rest]]></category>

		<guid isPermaLink="false">http://blog.picloud.com/?p=389</guid>
		<description><![CDATA[
We&#8217;ve been devoting significant time to making PiCloud a useful utility outside of the Python ecosystem. The first feature we have to showcase this is the ability to publish a Python function to a URL. There are a few reasons you might want to do this:



To call Python functions from a programming language other than [...]]]></description>
			<content:encoded><![CDATA[<p>
We&#8217;ve been devoting significant time to making PiCloud a useful utility outside of the Python ecosystem. The first feature we have to showcase this is the ability to publish a Python function to a URL. There are a few reasons you might want to do this:
</p>
<p><!-- add space --></p>
<ol>
<li>To call Python functions from a programming language other than Python. For example, if you&#8217;re integrating the PiCloud platform into a Java codebase, or even into a smartphone application (Android or iPhone).</li>
<li>To use PiCloud from Google AppEngine, since our <code>cloud</code> client library is not supported on GAE.</li>
<li>Because you&#8217;re tired of setting up web application projects when what you really need is a scalable RPC system.</li>
</ol>
<p>
In this post, we&#8217;ll give you your first taste of publishing functions on the web.
</p>
<h3>Define your Function</h3>
<p>
Just like when you offload regular computation to PiCloud, feel free to do anything in your function including importing custom libraries and making external connections.
</p>
<pre class="brush: python; title: ; notranslate">
def add(x, y):
    &quot;&quot;&quot;This function adds!&quot;&quot;&quot;
    return x+y
</pre>
<h3>Publish It</h3>
<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; import cloud
&gt;&gt;&gt; cloud.setkey(key, secret_key)
&gt;&gt;&gt; cloud.rest.publish(add, 'addition')
'https://api.picloud.com/r/2/addition'
</pre>
<p>
The first argument, <code>add</code>, is your function. The second argument, <code>addition</code>, is a label so you can reference the function later; it&#8217;s also present in the returned URL for clarity. For a list of all other arguments, refer to the <a href="http://docs.picloud.com/moduledoc.html#module-cloud.rest"><code>cloud.rest</code> module documentation</a>.
</p>
<p>
Let&#8217;s get information about the function we just published by making a GET request on the returned url. We recommend <a href="http://curl.haxx.se/">curl</a> to do this from a shell. We authenticate requests using <a href="http://en.wikipedia.org/wiki/Basic_access_authentication">basic authentication</a>. In curl, use &#8220;-u&#8221; as shown below to specify your key as your username, and secret key as your password. Note that we automatically extract the function&#8217;s doc string as the description.
</p>
<pre class="brush: bash; title: ; notranslate">
$ curl -k -u 'key:secret_key' https://api.picloud.com/r/2/addition/
{&quot;output_encoding&quot;: &quot;json&quot;, &quot;version&quot;: &quot;0.1&quot;, &quot;description&quot;: &quot;This function adds!&quot;, &quot;signature&quot;: &quot;addition(x, y)&quot;, &quot;uri&quot;: &quot;https://api.picloud.com/r/2/addition&quot;, &quot;label&quot;: &quot;addition&quot;}
</pre>
<p>
You can also see your published functions from your <a href="https://www.picloud.com/accounts/rest/">account control panel</a>.
</p>
<p><a href="http://media.picloud.com/img/blog/rest_ui_panel.png"><img src="http://media.picloud.com/img/blog/rest_ui_panel.png" alt="" title="rest_ui_panel" class="alignnone size-medium wp-image-436" /></a></p>
<h3>Call the Published Function</h3>
<p>
Now let&#8217;s call the function by using a POST request to the same URL. To specify arguments to the function <code>add</code>, you simply pass them in as <a href="http://en.wikipedia.org/wiki/JSON">JSON</a> encoded POST values. In this case, you would specify the POST values <code>x</code> and <code>y</code>.
</p>
<pre class="brush: bash; title: ; notranslate">
$ curl -k -u 'key:secret_key' https://api.picloud.com/r/2/addition/ -d x=1 -d y=1
{'jid': 809730}
</pre>
<h3>Get the Result</h3>
<p>
There are two ways we can grab the result of this job. The standard way is through your Python console:
</p>
<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; import cloud
&gt;&gt;&gt; cloud.setkey(key, secret_key)
&gt;&gt;&gt; cloud.result(809730)
2
</pre>
<p>
The language-agnostic way to do this using our REST API is to query the following URL: <code>https://api.picloud.com/job/{job_id}/result/</code>.
</p>
<pre class="brush: bash; title: ; notranslate">
$ curl -k -u 'key:secret_key' https://api.picloud.com/job/809730/result/
{&quot;result&quot;: 2}
</pre>
<p>
The difference between these two methods is that <code>cloud.result</code> will block until the result is ready; our REST API will return a &#8220;job not done&#8221; error, so you&#8217;ll have to keep querying until it&#8217;s ready.
</p>
<p>
For a full specification of our API, please see our <a href="http://docs.picloud.com/rest.html">REST API documentation</a>.
</p>
<h3>Taking Advantage of JSON Arguments</h3>
<p>
Since arguments are specified as JSON, you can easily pass in strings, lists, and dictionaries into your published functions. For example, we can concatenate two strings using our addition function:
</p>
<pre class="brush: bash; title: ; notranslate">
$ curl -k -u 'key:secret_key' https://api.picloud.com/r/2/addition -d &quot;x=\&quot;Hello, \&quot;&quot; -d &quot;y=\&quot;World\&quot;&quot;
{'jid': 809731}
$ curl -k -u 'key:secret_key' https://api.picloud.com/job/809731/result/
{&quot;result&quot;: &quot;Hello, World&quot;}
</pre>
<p>
We can also merge two lists using our addition function:
</p>
<pre class="brush: bash; title: ; notranslate">
$ curl -k -u 'key:secret_key' https://api.picloud.com/r/2/addition -d &quot;x=[1,2,3]&quot; -d &quot;y=[4,5,6]&quot;
{'jid': 809732}
$ curl -k -u 'key:secret_key' https://api.picloud.com/job/809732/result/
{&quot;result&quot;: [1, 2, 3, 4, 5, 6]}
</pre>
<p>
These work, of course, because in Python the addition operator can be applied to strings and lists, not just numbers.
</p>
<h3>Handling Raw Data</h3>
<p>
JSON does not natively support binary data. While you can encode the data to base64, and decode it in your function, we offer a more straightforward and efficient method. Binary data can be passed into a published function by using multipart/form-data as a file upload (MIME Content-Disposition sub-header has a <code>filename</code> parameter).
</p>
<p><b>Example</b></p>
<p>
To showcase raw data handling, we&#8217;re going to publish a function to create thumbnails. We&#8217;ll use this picture of Albert Einstein.
</p>
<p><center><br />
<a href="http://media.picloud.com/img/blog/albert_einstein.jpg"><img src="http://media.picloud.com/img/blog/albert_einstein.jpg" alt="" title="Albert Einstein" class="alignnone size-full wp-image-455" /></a><br />
</center></p>
<p>
Here&#8217;s the function we&#8217;ll use to create a thumbnail of an image. We use <code>StringIO</code> so that we can open and save the image in a memory buffer, rather than to a file.
</p>
<pre class="brush: python; title: ; notranslate">
from PIL import Image
from cStringIO import StringIO

def thumbnail(raw_img_data, width=50, height=50, output_format='JPEG'):
    im = Image.open(StringIO(raw_img_data))
    im.thumbnail((width, height))
    out_data = StringIO()
    im.save(out_data, output_format)
    return out_data.getvalue()

import cloud
# be sure to set the output encoding to raw
cloud.rest.publish(thumbnail, 'thumbnail', out_encoding='raw')
</pre>
<p>
Call the function. Use -F in conjunction with the @ symbol to POST an image file as a file upload, which will be treated as raw data by PiCloud. We can adjust the width and height by passing in POST values, or if we omit them, the default value of 50 will be used.
</p>
<pre class="brush: bash; title: ; notranslate">
$ curl -k -u 'key:secret_key' -F width=60 -F height=76 -F &quot;raw_img_data=@albert_einstein.jpg&quot; https://api.picloud.com/r/2/thumbnail/
{'jid': 809737}
</pre>
<p>
The content of the result is the binary data representing the thumbnail image. Unlike JSON encoded results, there is no enclosing dictionary. Thus, all you have to do to see the image is pipe the result of the job into a file.
</p>
<pre class="brush: bash; title: ; notranslate">
$ curl -k -u 'key:secret_key' https://api.picloud.com/job/809737/result/ &gt; albert_einstein.thumb.jpg
</pre>
<p>
Open the thumbnail in your favorite image program!
</p>
<p><a href="http://media.picloud.com/img/blog/albert_einstein.thumb.jpg"><img src="http://media.picloud.com/img/blog/albert_einstein.thumb.jpg" alt="Albert Einstein Thumbnail" title="albert_einstein.thumb" class="alignnone size-full wp-image-460" /></a></p>
<h3>Conclusion: Take a rest, and then give it a spin!</h3>
<p>
We&#8217;re particularly excited by function publishing because it bridges PiCloud with the world outside of Python, and in doing so, brings all the computing benefits of our standard service. You can publish functions without any care for the amount of hardware running underneath. As your functions get called more frequently, we automatically scale our servers to meet demand. You can also reserve real-time cores if they want to guarantee a certain number of cores at all times. Lastly, you can be confident that your computation is being run on a system built with performance, robustness, and redundancy at its core.
</p>
<p>
If this technology captivates you, <a href="http://www.twitter.com/picloud">follow us on Twitter</a>, or go above and beyond and <a href="http://www.picloud.com/jobs/">join our team</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.picloud.com/2011/09/14/introducing-function-publishing-via-rest/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Introducing High-Memory Cores</title>
		<link>http://blog.picloud.com/2011/09/02/introducing-high-memory-cores/</link>
		<comments>http://blog.picloud.com/2011/09/02/introducing-high-memory-cores/#comments</comments>
		<pubDate>Sat, 03 Sep 2011 01:06:29 +0000</pubDate>
		<dc:creator>Ken Elkabany</dc:creator>
				<category><![CDATA[What's New]]></category>
		<category><![CDATA[core types]]></category>
		<category><![CDATA[high memory]]></category>
		<category><![CDATA[new features]]></category>

		<guid isPermaLink="false">http://blog.picloud.com/?p=357</guid>
		<description><![CDATA[
When we first launched PiCloud, we provided two options for processing power: standard and high cpu. Standard provided 1 compute unit with 300MB of RAM, while high cpu provided 2.5 compute units and 800MB of RAM. But what about tasks that require GBs of memory and an even faster CPU? Enter core types.


You can now [...]]]></description>
			<content:encoded><![CDATA[<p>
When we first launched PiCloud, we provided two options for processing power: standard and high cpu. Standard provided 1 compute unit with 300MB of RAM, while high cpu provided 2.5 compute units and 800MB of RAM. But what about tasks that require GBs of memory and an even faster CPU? Enter <b>core types</b>.
</p>
<p>
You can now select the type of core you want your job to be run on.
</p>
<ul style="margin-left: 1.5em;">
<li><b>c1</b>: Replaces our standard option as default.</li>
<li><b>c2</b>: Replaces the high cpu option.</li>
<li><b>m1</b>: Our new high-memory core with 3.25 compute units and 8GB of memory.</li>
</ul>
<p>
For more details, see our updated <a href="http://www.picloud.com/pricing/">pricing page</a>.
</p>
<h3>How to Use It</h3>
<p>
We&#8217;re committed to maintaining an extraordinarily simple API for you. With our old library you would do the following:
</p>
<pre class="brush: python; title: ; notranslate">
cloud.call(func, _high_cpu=True)
</pre>
<p>
With our new library (available <a href="https://www.picloud.com/accounts/start/">here</a>), you do this instead:
</p>
<pre class="brush: python; title: ; notranslate">
cloud.call(func, _type='c2')
</pre>
<h3>Additional Information</h3>
<p>
In conjunction with these changes, real-time cores are now reserved by type. You can see the new interface in your <a href="https://www.picloud.com/accounts/realtime/">control panel</a>.
</p>
<p>
We&#8217;ll be releasing more cores as we hear demand for them. Our next core, <b>s1</b>, which is beta, is a solution for users on our platform who scrape the web. When running jobs in parallel on s1 cores, each job will have its own IP, minimizing throttling effects. However, consecutive jobs may share the same IP address.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.picloud.com/2011/09/02/introducing-high-memory-cores/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Crons in the Cloud!</title>
		<link>http://blog.picloud.com/2010/08/10/crons-in-the-cloud/</link>
		<comments>http://blog.picloud.com/2010/08/10/crons-in-the-cloud/#comments</comments>
		<pubDate>Wed, 11 Aug 2010 02:04:02 +0000</pubDate>
		<dc:creator>Ken Elkabany</dc:creator>
				<category><![CDATA[What's New]]></category>
		<category><![CDATA[cron]]></category>
		<category><![CDATA[new features]]></category>

		<guid isPermaLink="false">http://blog.picloud.com/?p=273</guid>
		<description><![CDATA[We&#8217;re pleased to announce the addition of crons to the PiCloud platform. A cron is a simple way to schedule a function to be run periodically. Time and dates are specified using the standard crontab format. Crons can be triggered as often as every minute, and there&#8217;s no limit to the number of functions you [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;re pleased to announce the addition of crons to the PiCloud platform. A <a href="http://en.wikipedia.org/wiki/Cron">cron</a> is a simple way to schedule a function to be run periodically. Time and dates are specified using the standard <a href="http://unixhelp.ed.ac.uk/CGI/man-cgi?crontab+5">crontab format</a>. Crons can be triggered as often as every minute, and there&#8217;s no limit to the number of functions you can register as crons. You will be billed for the amount of compute time consumed by the function triggered by your cron&#8211;just like if you were running a function on PiCloud. We have also added a tab to the web interface for managing crons.</p>
<p>Here&#8217;s how to register a cron:</p>
<pre class="brush: python; title: ; notranslate">
# registers function ping_webserver with the label heartbeat
# this function could be checking whether a webservice is active
cloud.cron.register(ping_webserver, 'heartbeat', '* * * * *') # runs every minute
</pre>
<p>When you no longer need a cron, you can deregister it via our web interface or using the following:</p>
<pre class="brush: python; title: ; notranslate">
# deregister function ping_webserver with the label heartbeat
cloud.cron.deregister('ping_webserver')
</pre>
<p>Here&#8217;s a function that runs once a day at noon.</p>
<pre class="brush: python; title: ; notranslate">
# 19 is the 19th GMT hour, which translates to 12pm PDT (GMT -7)
cloud.cron.register(sudo_make_me_a_sandwich, 'lunch', '0 19 * * *')
</pre>
<p>That&#8217;s all it takes! See our <a href="http://docs.picloud.com/moduledoc.html#module-cloud.cron">documentation for the full cron specification</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.picloud.com/2010/08/10/crons-in-the-cloud/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Store your files with PiCloud!</title>
		<link>http://blog.picloud.com/2010/05/03/store-your-files-with-picloud/</link>
		<comments>http://blog.picloud.com/2010/05/03/store-your-files-with-picloud/#comments</comments>
		<pubDate>Tue, 04 May 2010 00:24:53 +0000</pubDate>
		<dc:creator>Ken Elkabany</dc:creator>
				<category><![CDATA[What's New]]></category>
		<category><![CDATA[new features]]></category>

		<guid isPermaLink="false">http://blog.picloud.com/?p=101</guid>
		<description><![CDATA[One of the most frequent questions we get is &#8220;where do I put my data?&#8221; To this, we&#8217;ve always had the same answer: Anywhere you want. Unlike other platforms, we&#8217;ve never believed in locking in your data into our proprietary data store. Our users keep data in all sorts of different places (AWS, Rackspace, or [...]]]></description>
			<content:encoded><![CDATA[<p>One of the most frequent questions we get is &#8220;where do I put my data?&#8221; To this, we&#8217;ve always had the same answer: Anywhere you want. Unlike other platforms, we&#8217;ve never believed in locking in your data into our proprietary data store. Our users keep data in all sorts of different places (AWS, Rackspace, or on their local machines), and in all different forms (flat files, relational databases, and key stores). We don&#8217;t plan to change this, because we don&#8217;t believe we can provide the single best data storage solution to satisfy everyone&#8217;s needs. We&#8217;re big fans of using the correct tool for every problem.</p>
<p>So what is our new file storage solution? It&#8217;s a simple and easy way for our users to get their data on the cloud to be crunched by PiCloud. We don&#8217;t pretend that it&#8217;s the holy grail of data storage solutions, but it&#8217;s a solid answer for users who don&#8217;t already have a data store setup. If you don&#8217;t need it, you won&#8217;t be affected.</p>
<p>The module is included in our <code>cloud</code> library as <code>cloud.files</code>. Here&#8217;s the most basic way to use it:<br />
<code><br />
cloud.files.put('data.txt')   # stores data.txt on the cloud<br />
cloud.files.get('data.txt')   # saves data.txt onto your machine<br />
cloud.files.getf('data.txt')  # gets a stream of the contents of data.txt<br />
</code></p>
<p>See our documentation for the <a href="http://docs.picloud.com/moduledoc.html#module-cloud.files">full specification</a> and <a href="http://docs.picloud.com/basic_examples.html#cloud-files">examples</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.picloud.com/2010/05/03/store-your-files-with-picloud/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>New Users, New Features, and PyCon!</title>
		<link>http://blog.picloud.com/2010/02/19/new-users-new-features-and-pycon/</link>
		<comments>http://blog.picloud.com/2010/02/19/new-users-new-features-and-pycon/#comments</comments>
		<pubDate>Fri, 19 Feb 2010 08:00:48 +0000</pubDate>
		<dc:creator>Ken Elkabany</dc:creator>
				<category><![CDATA[What's New]]></category>
		<category><![CDATA[new features]]></category>
		<category><![CDATA[pycon]]></category>

		<guid isPermaLink="false">http://blog.picloud.com/?p=83</guid>
		<description><![CDATA[Wait no longer! We&#8217;ve opened up PiCloud to another batch of users today, and from now onward, we promise to accelerate the roll out of PiCloud to new users. For users, both new and old, I wanted to highlight some of the many changes we&#8217;ve made in the past month that haven&#8217;t necessarily been the [...]]]></description>
			<content:encoded><![CDATA[<p>Wait no longer! We&#8217;ve opened up PiCloud to another batch of users today, and from now onward, we promise to accelerate the roll out of PiCloud to new users. For users, both new and old, I wanted to highlight some of the many changes we&#8217;ve made in the past month that haven&#8217;t necessarily been the most visible.</p>
<p><strong>Variable Compute Units</strong><br />
We had customers asking us for more powerful CPUs, and so we&#8217;ve delivered. With a simple keyword argument change, you can now switch between using 1 Compute Unit (1-1.2 ghz Xeon) to 2.5 Compute Units (2.5-3ghz Xeon). Check it out (code):</p>
<p><code>cloud.call(cpu_intensive_func, _high_cpu=True) # uses 2.5 compute units</code></p>
<p><strong>Profiler Option</strong><br />
While we&#8217;ve gotten great feedback for profiling functions that run on PiCloud, we&#8217;ve also received requests to have the ability to turn off the profiler. After all, the deterministic profiler does have overhead that scales with the number of function calls in a script. To turn off the profiler, it&#8217;s simply another keyword argument _profile.</p>
<p><code>cloud.call(foo, _profiler=False)</code></p>
<p><strong>Drop in for multiprocessing</strong><br />
If you&#8217;re already using Python multiprocessing, but want to run your computation across our cluster, now you can. Check out our <a href="http://docs.picloud.com/client_adv.html#multiprocessing-pool-interface">docs</a> to see how.</p>
<p><strong>cloud library is now open source</strong><br />
We told users before that the client library was not open sourced, because frankly, we didn&#8217;t believe it was stable enough to deserve the attention of developers in the community. We are now at that point, so the client library has been released with an LGPL license.</p>
<p><strong>Inclusion in the Enthought Python Distribution (EPD)</strong><br />
<a href="http://www.enthought.com/products/epd.php">EPD</a> is ideal for scientists and engineers looking for an easy, standardized way to deploy a powerful set of scientific tools on their own computer or across a whole organization. As of the latest EPD release, 6.0, the cloud library is now included in the distribution. Welcome EPD customers!</p>
<p><strong>Bug fixes</strong><br />
Having hundreds of users using our platform is the easiest way to expose all the nitty-gritty bugs and race conditions that are lurking in our system. We would like to thank our ever-growing community for the many bug reports and critical fixes we have had over the past month.</p>
<p>Lastly, our CTO, Aaron Staley, and I will be at PyCon this weekend. Hope to see you all there!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.picloud.com/2010/02/19/new-users-new-features-and-pycon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

