<?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; What&#8217;s New</title>
	<atom:link href="http://blog.picloud.com/category/whats-new/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>20 Free Core Hours Every Month!</title>
		<link>http://blog.picloud.com/2011/10/24/20-free-core-hours-every-month/</link>
		<comments>http://blog.picloud.com/2011/10/24/20-free-core-hours-every-month/#comments</comments>
		<pubDate>Mon, 24 Oct 2011 23:31:04 +0000</pubDate>
		<dc:creator>Ken Elkabany</dc:creator>
				<category><![CDATA[What's New]]></category>
		<category><![CDATA[free core hours]]></category>

		<guid isPermaLink="false">http://blog.picloud.com/?p=729</guid>
		<description><![CDATA[
Starting this month, all users will get 20 c1 core hours worth of credits each and every month.


If you ran out of your original 5 core hour credits, you can come back and play around some more!
If you have minimal computing needs, this means that you can now use PiCloud regularly without even having to [...]]]></description>
			<content:encoded><![CDATA[<p>
Starting this month, all users will get 20 c1 core hours worth of credits each and every month.
</p>
<ul>
<li>If you ran out of your original 5 core hour credits, you can come back and play around some more!</li>
<li>If you have minimal computing needs, this means that you can now use PiCloud regularly without even having to enter a credit card.</li>
</ul>
<p>
Looking for more? Don&#8217;t forget, we&#8217;re giving away $500 worth of credits as part of our <a href="http://blog.picloud.com/2011/10/20/introducing-free-core-hours-for-academic-research/">Academic Research Program</a>. Applications are due this Thursday, October 27th.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.picloud.com/2011/10/24/20-free-core-hours-every-month/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Introducing Free Core Hours for Academic Research</title>
		<link>http://blog.picloud.com/2011/10/20/introducing-free-core-hours-for-academic-research/</link>
		<comments>http://blog.picloud.com/2011/10/20/introducing-free-core-hours-for-academic-research/#comments</comments>
		<pubDate>Thu, 20 Oct 2011 22:48:46 +0000</pubDate>
		<dc:creator>Ken Elkabany</dc:creator>
				<category><![CDATA[Academic Research Program]]></category>
		<category><![CDATA[What's New]]></category>
		<category><![CDATA[free core hours]]></category>

		<guid isPermaLink="false">http://blog.picloud.com/?p=718</guid>
		<description><![CDATA[
From the beginning, we&#8217;ve prided ourselves on bringing the cloud to scientists and engineers who don&#8217;t have access to a major compute cluster or lack the system administration know-how to operate one. And we&#8217;re indebted to the research groups around the world who quickly understood our value proposition, and enthusiastically adopted our platform. We could [...]]]></description>
			<content:encoded><![CDATA[<p>
From the beginning, we&#8217;ve prided ourselves on bringing the cloud to scientists and engineers who don&#8217;t have access to a major compute cluster or lack the system administration know-how to operate one. And we&#8217;re indebted to the research groups around the world who quickly understood our value proposition, and enthusiastically adopted our platform. We could not have gotten to where we are today without them. To return the favor, today we&#8217;re introducing the PiCloud Academic Research Program to grant <b>$500</b> (10,000 c1 core hours)<b> free</b> to two researchers.
</p>
<p>
Since this is the first time we&#8217;re doing this, we want to keep it simple. If you wish to apply, send an e-mail to <a href="mailto:research-funding@picloud.com?subject=Application for the PiCloud Academic Research Program">research-funding@picloud.com</a> by <b>Thursday, October 27th</b> with the following:
</p>
<ol>
<li>Full name</li>
<li>Organization or educational Institution</li>
<li>Your position</li>
<li>Short biography</li>
<li>A summary of your research field and project. Feel free to include conference papers, publications, and links to project websites. Please emphasize how PiCloud&#8217;s compute power will facilitate your research.</li>
</ol>
<p>
We will be awarding two submissions with free core hours. Winning researchers will also have an opportunity to get larger exposure for their projects on our blog and website. We&#8217;re looking forward to your submissions!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.picloud.com/2011/10/20/introducing-free-core-hours-for-academic-research/feed/</wfw:commentRss>
		<slash:comments>2</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>Our Pricing Model</title>
		<link>http://blog.picloud.com/2010/06/04/our-pricing-model/</link>
		<comments>http://blog.picloud.com/2010/06/04/our-pricing-model/#comments</comments>
		<pubDate>Sat, 05 Jun 2010 00:39:20 +0000</pubDate>
		<dc:creator>Ken Elkabany</dc:creator>
				<category><![CDATA[What's New]]></category>
		<category><![CDATA[pricing]]></category>

		<guid isPermaLink="false">http://blog.picloud.com/?p=141</guid>
		<description><![CDATA[Since the beginning of the year, we&#8217;ve been tweaking our pricing scheme to no avail. Just last month we published a new pricing page that we admitted wasn&#8217;t perfect, but was, we felt, as good as it would ever get. A key attribute of that system was the &#8220;parallelism limit,&#8221; the total number of cores [...]]]></description>
			<content:encoded><![CDATA[<p>Since the beginning of the year, we&#8217;ve been tweaking our pricing scheme to no avail. Just last month we published a new pricing page that we admitted wasn&#8217;t perfect, but was, we felt, as good as it would ever get. A key attribute of that system was the &#8220;parallelism limit,&#8221; the total number of cores we would devote to your computation at any one time. The higher the parallelism limit, the more we would charge per compute unit hour.</p>
<p>We quickly realized that our users weren&#8217;t fans of this. It&#8217;s roughly equivalent to Amazon charging a higher hourly rate for every additional instance booted up, which is a disincentive to users looking to use hundreds of cores of processing power. Some users cleverly created multiple accounts, each with the cheapest 10 compute unit parallelism limit, and used them in concert to run their computation with a very high parallelism limit.</p>
<p>We weren&#8217;t fans either. We had users choose their parallelism limit so we could provision enough servers ahead of time to respond quickly to their computational demands. That was good in theory, but it meant that we had to maintain a large pool of servers even when our users weren&#8217;t running functions. Wasted compute cycles meant that we had to raise all of our prices, even for users who didn&#8217;t need immediate response times.</p>
<p><strong>New Model</strong><br />
Our solution was to drop the idea of a parallelism limit altogether.</p>
<p>Now, our vanilla service doesn&#8217;t guarantee when functions will begin processing. In the background, we&#8217;re adding our users&#8217; functions to a fair-queuing scheduler. We estimate the amount of workload in the queue, and automatically scale our cluster as we see fit. Most functions don&#8217;t wait very long; you can see <a href="http://www.picloud.com/product/#delayed_execution">empirical data on our product page</a>. If you&#8217;re looking for a cheap and effective batch-processing solution, this is it.</p>
<p>Real time compute units now serve a clear purpose. These are compute units that we reserve just for you. When you make a <code>cloud.call()</code>, your function will run immediately if you have any real time compute units available (not allocated to another one of your functions). If your real time compute units are fully utilized, then your function will wait until a real time compute unit becomes available, or if room exists in our fair-queuing system. This is the ideal solution for those who need real time response requirements, or simply want to accelerate their processing time. We charge a minimal amount ($0.015 per compute unit hour) to reserve real time units in hourly increments. This minimal cost exists to protect ourselves in case you don&#8217;t run any functions, since we&#8217;re reserving space on Amazon instances for you.</p>
<p>I hope this sheds light on why our pricing model has been in flux. Our team is genuinely happy with this latest pricing model, because it accurately structures the value we provide our customers. If you have any questions, thoughts, or concerns, we&#8217;d love to hear what you have to say in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.picloud.com/2010/06/04/our-pricing-model/feed/</wfw:commentRss>
		<slash:comments>0</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>

