Sophie

Sophie

distrib > Fedora > 14 > x86_64 > media > updates > by-pkgid > 762e4b4e451f9de4722602c03fda2c9b > files > 230

python-fedora-0.3.25.1-1.fc14.1.noarch.rpm



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>Fedora Services &mdash; python-fedora v0.3.25.1 documentation</title>
    <link rel="stylesheet" href="_static/default.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '',
        VERSION:     '0.3.25.1',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="_static/jquery.js"></script>
    <script type="text/javascript" src="_static/underscore.js"></script>
    <script type="text/javascript" src="_static/doctools.js"></script>
    <link rel="search" type="application/opensearchdescription+xml"
          title="Search within python-fedora v0.3.25.1 documentation"
          href="_static/opensearch.xml"/>
    <link rel="top" title="python-fedora v0.3.25.1 documentation" href="index.html" />
    <link rel="next" title="CSRF Protection" href="CSRF.html" />
    <link rel="prev" title="Existing Services" href="existing.html" /> 
  </head>
  <body>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="CSRF.html" title="CSRF Protection"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="existing.html" title="Existing Services"
             accesskey="P">previous</a> |</li>
        <li><a href="index.html">python-fedora v0.3.25.1 documentation</a> &raquo;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="fedora-services">
<span id="id1"></span><h1>Fedora Services<a class="headerlink" href="#fedora-services" title="Permalink to this headline">¶</a></h1>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Authors:</th><td class="field-body">Toshio Kuratomi
Luke Macken</td>
</tr>
<tr class="field"><th class="field-name">Date:</th><td class="field-body">02 February 2009</td>
</tr>
<tr class="field"><th class="field-name">For Version:</th><td class="field-body">0.3.x</td>
</tr>
</tbody>
</table>
<p>In the loosest sense, a Fedora Service is a web application that sends data
that <a class="reference internal" href="api.html#fedora.client.BaseClient" title="fedora.client.BaseClient"><tt class="xref py py-class docutils literal"><span class="pre">BaseClient</span></tt></a> is able to understand.  This document
defines things that a web application must currently do for
<a class="reference internal" href="api.html#fedora.client.BaseClient" title="fedora.client.BaseClient"><tt class="xref py py-class docutils literal"><span class="pre">BaseClient</span></tt></a> to understand it.</p>
<div class="section" id="module-fedora.tg">
<span id="turbogears-and-fedora-tg"></span><h2>TurboGears and fedora.tg<a class="headerlink" href="#module-fedora.tg" title="Permalink to this headline">¶</a></h2>
<p>Functions and classes to help build a Fedora Service.</p>
<p>All current Fedora Services are written in <a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a>.  Examples in
this document will be for that framework.  However, other frameworks can be
used to write a Service if they can correctly create the data that
<a class="reference internal" href="api.html#fedora.client.BaseClient" title="fedora.client.BaseClient"><tt class="xref py py-class docutils literal"><span class="pre">BaseClient</span></tt></a> needs.</p>
<p>A Fedora Service differs from other web applications in that certain URLs for
the web application are an API layer that the Service can send and receive
<a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> data from for <a class="reference internal" href="api.html#fedora.client.BaseClient" title="fedora.client.BaseClient"><tt class="xref py py-class docutils literal"><span class="pre">BaseClient</span></tt></a> to interpret.
This imposes certain constraints on what data can be sent and what data can be
received from those URLs.  The <a class="reference internal" href="#module-fedora.tg" title="fedora.tg"><tt class="xref py py-mod docutils literal"><span class="pre">fedora.tg</span></tt></a> module contains functions that
help you write code that communicated well with
<a class="reference internal" href="api.html#fedora.client.BaseClient" title="fedora.client.BaseClient"><tt class="xref py py-class docutils literal"><span class="pre">BaseClient</span></tt></a>.</p>
<p>The <a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a> framework separates an application into <a class="reference internal" href="glossary.html#term-model"><em class="xref std std-term">model</em></a>,
<a class="reference internal" href="glossary.html#term-view"><em class="xref std std-term">view</em></a>, and <a class="reference internal" href="glossary.html#term-controller"><em class="xref std std-term">controller</em></a> layers.  The model is typically a
database and holds the raw data that the application needs.  The view formats
the data before output.  The controller makes decisions about what data to
retrieve from the model and which view to pass it onto.  The code that you&#8217;ll
most often need to use from <a class="reference internal" href="#module-fedora.tg" title="fedora.tg"><tt class="xref py py-mod docutils literal"><span class="pre">fedora.tg</span></tt></a> operates on the <a class="reference internal" href="glossary.html#term-controller"><em class="xref std std-term">controller</em></a>
layer but there&#8217;s also code that works on the model and view behind the scenes.</p>
</div>
<div class="section" id="module-fedora.tg.utils">
<span id="controllers"></span><h2>Controllers<a class="headerlink" href="#module-fedora.tg.utils" title="Permalink to this headline">¶</a></h2>
<p>Miscellaneous functions of use on a TurboGears Server</p>
<p class="versionchanged">
<span class="versionmodified">Changed in version 0.3.14: </span>Save the original turbogears.url function as <tt class="xref py py-func docutils literal"><span class="pre">fedora.tg.util.tg_url()</span></tt></p>
<p class="versionchanged">
<span class="versionmodified">Changed in version 0.3.17: </span>Renamed from fedora.tg.util</p>
<p class="versionchanged">
<span class="versionmodified">Changed in version 0.3.25: </span>Renamed from fedora.tg.tg1utils</p>
<p><em>Module author: Toshio Kuratomi &lt;<a class="reference external" href="mailto:tkuratom&#37;&#52;&#48;redhat&#46;com">tkuratom<span>&#64;</span>redhat<span>&#46;</span>com</a>&gt;</em></p>
<p><em>Module author: Ricky Zhou &lt;<a class="reference external" href="mailto:ricky&#37;&#52;&#48;fedoraproject&#46;org">ricky<span>&#64;</span>fedoraproject<span>&#46;</span>org</a>&gt;</em></p>
<p>The <a class="reference internal" href="glossary.html#term-controller"><em class="xref std std-term">controller</em></a> is the code that processes an http request.  It
validates and processes requests and parameters sent by the user, gets data
from the model to satisfy the request, and then passes it onto a view layer to
be returned to the user.  <a class="reference internal" href="#module-fedora.tg.utils" title="fedora.tg.utils"><tt class="xref py py-mod docutils literal"><span class="pre">fedora.tg.utils</span></tt></a> contains several helpful
functions for working with controllers.</p>
</div>
<div class="section" id="urls-as-api">
<h2>URLs as API<a class="headerlink" href="#urls-as-api" title="Permalink to this headline">¶</a></h2>
<dl class="function">
<dt id="fedora.tg.utils.request_format">
<tt class="descclassname">fedora.tg.utils.</tt><tt class="descname">request_format</tt><big>(</big><big>)</big><a class="headerlink" href="#fedora.tg.utils.request_format" title="Permalink to this definition">¶</a></dt>
<dd><p>Return the output format that was requested by the user.</p>
<p>The user is able to specify a specific output format using either the
<tt class="docutils literal"><span class="pre">Accept:</span></tt> HTTP header or the <tt class="docutils literal"><span class="pre">tg_format</span></tt> query parameter.  This
function checks both of those to determine what format the reply should
be in.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Return type:</th><td class="field-body">string</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">The requested format.  If none was specified, &#8216;default&#8217; is
returned</td>
</tr>
</tbody>
</table>
<p class="versionchanged">
<span class="versionmodified">Changed in version 0.3.17: </span>Return symbolic names for json, html, xhtml, and xml instead of
letting raw mime types through</p>
</dd></dl>

<dl class="function">
<dt id="fedora.tg.utils.jsonify_validation_errors">
<tt class="descclassname">fedora.tg.utils.</tt><tt class="descname">jsonify_validation_errors</tt><big>(</big><big>)</big><a class="headerlink" href="#fedora.tg.utils.jsonify_validation_errors" title="Permalink to this definition">¶</a></dt>
<dd><p>Return an error for <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> if validation failed.</p>
<p>This function checks for two things:</p>
<ol class="arabic simple">
<li>We&#8217;re expected to return <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> data.</li>
<li>There were errors in the validation process.</li>
</ol>
<p>If both of those are true, this function constructs a response that
will return the validation error messages as <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> data.</p>
<p>All controller methods that are error_handlers need to use this:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="nd">@expose</span><span class="p">(</span><span class="n">template</span><span class="o">=</span><span class="s">&#39;templates.numberform&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">enter_number</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
    <span class="n">errors</span> <span class="o">=</span> <span class="n">fedora</span><span class="o">.</span><span class="n">tg</span><span class="o">.</span><span class="n">util</span><span class="o">.</span><span class="n">jsonify_validation_errors</span><span class="p">()</span>
    <span class="k">if</span> <span class="n">errors</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">errors</span>
    <span class="p">[</span><span class="o">...</span><span class="p">]</span>

<span class="nd">@expose</span><span class="p">(</span><span class="n">allow_json</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="nd">@error_handler</span><span class="p">(</span><span class="n">enter_number</span><span class="p">)</span>
<span class="nd">@validate</span><span class="p">(</span><span class="n">form</span><span class="o">=</span><span class="n">number_form</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">save</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
    <span class="k">return</span> <span class="nb">dict</span><span class="p">(</span><span class="n">success</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
</pre></div>
</div>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Return type:</th><td class="field-body">None or dict</td>
</tr>
<tr class="field"><th class="field-name">Returns :</th><td class="field-body">None if there are no validation errors or <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> isn&#8217;t
requested, otherwise a dictionary with the error that&#8217;s suitable for
return from the controller.  The error message is set in tg_flash
whether <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> was requested or not.</td>
</tr>
</tbody>
</table>
</dd></dl>

<dl class="function">
<dt id="fedora.tg.utils.json_or_redirect">
<tt class="descclassname">fedora.tg.utils.</tt><tt class="descname">json_or_redirect</tt><big>(</big><em>forward_url</em><big>)</big><a class="headerlink" href="#fedora.tg.utils.json_or_redirect" title="Permalink to this definition">¶</a></dt>
<dd><p>If <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> is requested, return a dict, otherwise redirect.</p>
<p>This is a decorator to use with a method that returns <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> by
default.  If <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> is requested, then it will return the dict from
the method.  If <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> is not requested, it will redirect to the
given URL.  The method that is decorated should be constructed so that it
calls turbogears.flash() with a message that will be displayed on the
forward_url page.</p>
<p>Use it like this:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">turbogears</span>

<span class="nd">@json_or_redirect</span><span class="p">(</span><span class="s">&#39;http://localhost/calc/&#39;</span><span class="p">)</span>
<span class="nd">@expose</span><span class="p">(</span><span class="n">allow_json</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">divide</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dividend</span><span class="p">,</span> <span class="n">divisor</span><span class="p">):</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">answer</span> <span class="o">=</span> <span class="n">dividend</span> <span class="o">*</span> <span class="mf">1.0</span> <span class="o">/</span> <span class="n">divisor</span>
    <span class="k">except</span> <span class="ne">ZeroDivisionError</span><span class="p">:</span>
        <span class="n">turbogears</span><span class="o">.</span><span class="n">flash</span><span class="p">(</span><span class="s">&#39;Division by zero not allowed&#39;</span><span class="p">)</span>
        <span class="k">return</span> <span class="nb">dict</span><span class="p">(</span><span class="n">exc</span><span class="o">=</span><span class="s">&#39;ZeroDivisionError&#39;</span><span class="p">)</span>
    <span class="n">turbogears</span><span class="o">.</span><span class="n">flash</span><span class="p">(</span><span class="s">&#39;The quotient is </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="n">answer</span><span class="p">)</span>
    <span class="k">return</span> <span class="nb">dict</span><span class="p">(</span><span class="n">quotient</span><span class="o">=</span><span class="n">answer</span><span class="p">)</span>
</pre></div>
</div>
<p>In the example, we return either an exception or an answer, using
<tt class="xref py py-func docutils literal"><span class="pre">turbogears.flash()</span></tt> to tell people of the result in either case.  If
<a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> data is requested, the user will get back a <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a>
string with the proper information.  If html is requested, we will be
redirected to &#8216;<a class="reference external" href="http://localhost/calc/">http://localhost/calc/</a>&#8216; where the flashed message will be
displayed.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><strong>forward_url</strong> &#8211; If <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> was not requested, redirect to this URL
after.</td>
</tr>
</tbody>
</table>
<p class="versionadded">
<span class="versionmodified">New in version 0.3.7: </span>To make writing methods that use validation easier</p>
</dd></dl>

<p>In <a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a> and most web frameworks, a URL is a kind of API for
accessing the data your web app provides.  This data can be made available in
multiple formats.  <a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a> allows you to use one URL to serve
multiple formats by specifying a query parameter or a special header.</p>
<div class="section" id="selecting-json-output">
<h3>Selecting JSON Output<a class="headerlink" href="#selecting-json-output" title="Permalink to this headline">¶</a></h3>
<p>A URL in <a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a> can serve double duty by returning multiple
formats depending on how it is called.  In most cases, the URL will return
HTML or XHTML by default.  By adding the query parameter, <tt class="docutils literal"><span class="pre">tg_format=json</span></tt>
you can switch from returning the default format to returning <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a>
data.  You need to add an <tt class="docutils literal"><span class="pre">&#64;expose(allow_json=True)</span></tt> decorator <a class="footnote-reference" href="#id4" id="id2">[1]</a> to your
controller method to tell <a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a> that this controller should
return <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> data:</p>
<div class="highlight-python"><pre>@expose(allow_json=True)
@expose(template='my.templates.amplifypage')
def amplify(self, data):</pre>
</div>
<p><tt class="docutils literal"><span class="pre">allow_json=True</span></tt> is a shortcut for this:</p>
<div class="highlight-python"><pre>@expose("json", content_type="text/javascript",
        as_format="json", accept_format="text/javascript")</pre>
</div>
<p>That means that the controller method will use the <tt class="docutils literal"><span class="pre">json</span></tt> template (uses
TurboJson to marshal the returned data to <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a>) to return data of type
<tt class="docutils literal"><span class="pre">text/javascript</span></tt> when either of these conditions is met:  a query param of
<tt class="docutils literal"><span class="pre">tg_format=json</span></tt> or an <tt class="docutils literal"><span class="pre">Accept:</span> <span class="pre">text/javascript</span></tt> header is sent.</p>
<p><a class="reference internal" href="api.html#fedora.client.BaseClient" title="fedora.client.BaseClient"><tt class="xref py py-class docutils literal"><span class="pre">BaseClient</span></tt></a> in python-fedora 0.1.x and 0.2.x use the
query parameter method of selecting <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> output.
<a class="reference internal" href="api.html#fedora.client.BaseClient" title="fedora.client.BaseClient"><tt class="xref py py-class docutils literal"><span class="pre">BaseClient</span></tt></a> 0.2.99.6 and 0.3.x use both the header
method and the query parameter since the argument was made that the header
method is friendlier to other web frameworks.  0.4 intends to use the header
alone.  If you use <tt class="docutils literal"><span class="pre">allow_json=True</span></tt> this change shouldn&#8217;t matter.  If you
specify the <tt class="docutils literal"><span class="pre">&#64;expose(&quot;json&quot;)</span></tt> decorator only <tt class="docutils literal"><span class="pre">accept_format</span></tt> is set.  So
it is advisable to include both <tt class="docutils literal"><span class="pre">as_format</span></tt> and <tt class="docutils literal"><span class="pre">accept_format</span></tt> in your
decorator.  Note that this is a limitation of <a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a> &lt;= 1.0.4.4.
If your application is only going to run on <a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a> &gt; 1.0.4.4 you
should be able to use a plain <tt class="docutils literal"><span class="pre">&#64;expose(&quot;json&quot;)</span></tt> <a class="footnote-reference" href="#id5" id="id3">[2]</a>.</p>
<table class="docutils footnote" frame="void" id="id4" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id2">[1]</a></td><td><a class="reference external" href="http://docs.turbogears.org/1.0/ExposeDecorator#same-method-different-template">http://docs.turbogears.org/1.0/ExposeDecorator#same-method-different-template</a></td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id5" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id3">[2]</a></td><td><a class="reference external" href="http://trac.turbogears.org/ticket/1459#comment:4">http://trac.turbogears.org/ticket/1459#comment:4</a></td></tr>
</tbody>
</table>
</div>
<div class="section" id="why-two-formats-from-a-single-url">
<h3>Why Two Formats from a Single URL?<a class="headerlink" href="#why-two-formats-from-a-single-url" title="Permalink to this headline">¶</a></h3>
<p>When designing your URLs you might wonder why you&#8217;d want to return
<a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> and HTML from a single controller method instead of having two
separate controller methods.  For instance, separating the URLs into their own
namespaces might seem logical: <tt class="docutils literal"><span class="pre">/app/json/get_user/USERNAME</span></tt> as opposed to
<tt class="docutils literal"><span class="pre">/app/user/USERNAME</span></tt>.  Doing things with two URLs as opposed to one has both
benefits and drawbacks.</p>
<div class="section" id="benefits-of-one-method-handling-multiple-formats">
<h4>Benefits of One Method Handling Multiple Formats<a class="headerlink" href="#benefits-of-one-method-handling-multiple-formats" title="Permalink to this headline">¶</a></h4>
<ul class="simple">
<li>Usually less code as there&#8217;s only one controller method</li>
<li>When a user sees a page that they want to get data from, they can get it as
<a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> instead of screen scraping.</li>
<li>Forces the application designer to think more about the API that is being
provided to the users instead of just the needs of the web page they are
creating.</li>
<li>Makes it easier to see what data an application will need to implement an
alternate interface since you can simply look at the template code to see
what variables are being used on a particular page.</li>
</ul>
</div>
<div class="section" id="benefits-of-multiple-methods-for-each-format">
<h4>Benefits of Multiple Methods for Each Format<a class="headerlink" href="#benefits-of-multiple-methods-for-each-format" title="Permalink to this headline">¶</a></h4>
<ul class="simple">
<li>Avoids special casing for error handlers (See below)</li>
<li>Separates URLs that you intend users to grab <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> data from URLs
where you only want to display HTML.</li>
<li>Allows the URLs that support <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> to concentrate on trimming the
size of the data sent while URLs that only return HTML can return whole
objects.</li>
<li>Organization can be better if you don&#8217;t have to include all of the pages
that may only be useful for user interface elements.</li>
</ul>
<p>Personal use has found that allowing <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> requests on one controller
method works well for cases where you want the user to get data and for
traditional form based user interaction.  AJAX requests have been better
served via dedicated methods.</p>
</div>
</div>
</div>
<div class="section" id="return-values">
<h2>Return Values<a class="headerlink" href="#return-values" title="Permalink to this headline">¶</a></h2>
<p>The toplevel of the return values should be a dict.  This is the natural
return value for <a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a> applications.</p>
<div class="section" id="marshaling">
<h3>Marshaling<a class="headerlink" href="#marshaling" title="Permalink to this headline">¶</a></h3>
<p>All data should be encoded in <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> before being returned.  This is
normally taken care of automatically by <a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a> and simplejson.  If
you are returning non-builtin objects you may have to define an <a class="reference internal" href="#id9">__json__()</a>
method.</p>
</div>
<div class="section" id="unicode">
<h3>Unicode<a class="headerlink" href="#unicode" title="Permalink to this headline">¶</a></h3>
<p>simplejson (and probably other <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> libraries) will take care of
encoding Unicode strings to <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> so be sure that you are passing
Unicode strings around rather than encoded byte strings.</p>
</div>
<div class="section" id="error-handling">
<h3>Error Handling<a class="headerlink" href="#error-handling" title="Permalink to this headline">¶</a></h3>
<p>In python, error conditions are handled by raising an exception.  However,
an exception object will not propagate automatically through a return from
the server.  Instead we set several special variables in the returned data
to inform <a class="reference internal" href="api.html#fedora.client.BaseClient" title="fedora.client.BaseClient"><tt class="xref py py-class docutils literal"><span class="pre">BaseClient</span></tt></a> of any errors.</p>
<p>At present, when <a class="reference internal" href="api.html#fedora.client.BaseClient" title="fedora.client.BaseClient"><tt class="xref py py-class docutils literal"><span class="pre">BaseClient</span></tt></a> receives an error it raises an exception of its
own with the exception information from the server inside.  Raising the same
exception as the server is being investigated but may pose security risks so
hasn&#8217;t yet been implemented.</p>
<div class="section" id="exc">
<h4>exc<a class="headerlink" href="#exc" title="Permalink to this headline">¶</a></h4>
<p>All URLs which return <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> data should set the <tt class="docutils literal"><span class="pre">exc</span></tt> variable when
the method fails unexpectedly (a database call failed, a place where you would
normally raise an exception, or where you&#8217;d redirect to an error page if a
user was viewing the HTML version of the web app).  <tt class="docutils literal"><span class="pre">exc</span></tt> should be set to
the name of an exception and <a class="reference internal" href="#tg-flash">tg_flash</a> set to the message that would normally
be given to the exception&#8217;s constructor.  If the return is a success (expected
values are being returned from the method or a value was updated successfully)
<tt class="docutils literal"><span class="pre">exc</span></tt> may either be unset or set to <tt class="xref docutils literal"><span class="pre">None</span></tt>.</p>
</div>
<div class="section" id="tg-flash">
<h4>tg_flash<a class="headerlink" href="#tg-flash" title="Permalink to this headline">¶</a></h4>
<p>When viewing the HTML web app, <tt class="docutils literal"><span class="pre">tg_flash</span></tt> can be set with a message to
display to the user either on the next page load or via an AJAX handler.
When used in conjunction with <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a>, <tt class="docutils literal"><span class="pre">exc=EXCEPTIONNAME</span></tt>, and
<a class="reference internal" href="api.html#fedora.client.BaseClient" title="fedora.client.BaseClient"><tt class="xref py py-class docutils literal"><span class="pre">BaseClient</span></tt></a>, <tt class="docutils literal"><span class="pre">tg_flash</span></tt> should be set to an error
message that the client can use to identify what went wrong or display to the
user.  It&#8217;s equivalent to the message you would normally give when raising an
exception.</p>
</div>
<div class="section" id="authentication-errors">
<h4>Authentication Errors<a class="headerlink" href="#authentication-errors" title="Permalink to this headline">¶</a></h4>
<p>Errors in authentication are a special case.  Instead of returning an error
with <tt class="docutils literal"><span class="pre">exc='AuthError'</span></tt> set, the server should return with <tt class="docutils literal"><span class="pre">response.status</span> <span class="pre">=</span>
<span class="pre">403</span></tt>.  <a class="reference internal" href="api.html#fedora.client.BaseClient" title="fedora.client.BaseClient"><tt class="xref py py-class docutils literal"><span class="pre">BaseClient</span></tt></a> will see the 403 and raise an
<cite>AuthError</cite>.</p>
<p>This is the signal for the client to ask the user for new credentials (usually
a new username and password).</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Upstream <a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a> has switched to sending a 401 for
authentication problems.  However, their use of 401 is against the http
specification (It doesn&#8217;t set the &#8216;WWW-Authentication&#8217; header) and it
causes problems for konqueror and webkit based browsers so we probably
will not be switching.</p>
</div>
</div>
</div>
</div>
<div class="section" id="performing-different-actions-when-returning-json">
<h2>Performing Different Actions when Returning JSON<a class="headerlink" href="#performing-different-actions-when-returning-json" title="Permalink to this headline">¶</a></h2>
<p>So far we&#8217;ve run across three features of <a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a> that provide
value to a web application but don&#8217;t work when returning <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> data.
We provide a function that can code around this.
<tt class="docutils literal"><span class="pre">fedora.tg.utils.request_format()</span></tt> will return the format that the page
is being returned as.  Code can use this to check whether <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> output
is expected and do something different based on it:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">output</span> <span class="o">=</span> <span class="p">{</span><span class="s">&#39;tg_flash&#39;</span><span class="p">:</span> <span class="s">&#39;An Error Occurred&#39;</span><span class="p">}</span>
<span class="k">if</span> <span class="n">fedora</span><span class="o">.</span><span class="n">tg</span><span class="o">.</span><span class="n">utils</span><span class="o">.</span><span class="n">request_format</span><span class="p">()</span> <span class="o">==</span> <span class="s">&#39;json&#39;</span><span class="p">:</span>
    <span class="n">output</span><span class="p">[</span><span class="s">&#39;exc&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&#39;ServerError&#39;</span>
<span class="k">else</span><span class="p">:</span>
    <span class="n">output</span><span class="p">[</span><span class="s">&#39;tg_template&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&#39;my.templates.error&#39;</span>
<span class="k">return</span> <span class="n">output</span>
</pre></div>
</div>
<p>In this example, we return an error through our &#8220;exception&#8221; mechanism if we
are returning <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> and return an error page by resetting the template
if not.</p>
<div class="section" id="redirects">
<h3>Redirects<a class="headerlink" href="#redirects" title="Permalink to this headline">¶</a></h3>
<p>Redirects do not play well with <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> <a class="footnote-reference" href="#id7" id="id6">[3]</a> because <a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a>
is unable to turn the function returned from the redirect into a dictionary
that can be turned into <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a>.</p>
<p>Redirects are commonly used to express errors.  This is actually better
expressed using <a class="reference internal" href="#tg-template">tg_template</a> because that method leaves the URL intact.
That allows the end user to look for spelling mistakes in their URL.  If you
need to use a redirect, the same recipe as above will allow you to split your
code paths.</p>
<table class="docutils footnote" frame="void" id="id7" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id6">[3]</a></td><td>Last checked in TurboGears 1.0.4</td></tr>
</tbody>
</table>
</div>
<div class="section" id="tg-template">
<h3>tg_template<a class="headerlink" href="#tg-template" title="Permalink to this headline">¶</a></h3>
<p>Setting what template is returned to a user by setting tg_template in the
return dict (for instance, to display an error page without changing the URL)
is a perfectly valid way to use <a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a>.  Unfortunately, since
<a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> is simply another template in <a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a> you have to be
sure not to interfere with the generation of <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> data.  You need to
check whether <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> was requested using
<tt class="docutils literal"><span class="pre">fedora.tg.utils.request_format()</span></tt> and only return a different template
if that&#8217;s not the case.  The recipe above shows how to do this.</p>
</div>
<div class="section" id="validators">
<h3>Validators<a class="headerlink" href="#validators" title="Permalink to this headline">¶</a></h3>
<p>Validators are slightly different than the issues we&#8217;ve encountered so far.
Validators are used to check and convert parameters sent to a controller
method so that only good data is dealt with in the controller method itself.
The problem is that when a validator detects a parameter that is invalid, it
performs a special internal redirect to a method that is its <tt class="docutils literal"><span class="pre">error_handler</span></tt>.
We can&#8217;t intercept this redirect because it happens in the decorators before
our method is invoked.  So we have to deal with the aftermath of the redirect
in the <tt class="docutils literal"><span class="pre">error_handler</span></tt> method:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">NotNumberValidator</span><span class="p">(</span><span class="n">turbogears</span><span class="o">.</span><span class="n">validators</span><span class="o">.</span><span class="n">FancyValidator</span><span class="p">):</span>
    <span class="n">messages</span> <span class="o">=</span> <span class="p">{</span><span class="s">&#39;Number&#39;</span><span class="p">:</span> <span class="s">&#39;Numbers are not allowed&#39;</span><span class="p">}</span>

    <span class="k">def</span> <span class="nf">to_python</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">state</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">number</span> <span class="o">=</span> <span class="n">turbogears</span><span class="o">.</span><span class="n">validators</span><span class="o">.</span><span class="n">Number</span><span class="p">(</span><span class="n">value</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
        <span class="k">except</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">value</span>
        <span class="k">raise</span> <span class="n">validators</span><span class="o">.</span><span class="n">Invalid</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">message</span><span class="p">(</span><span class="s">&#39;Number&#39;</span><span class="p">,</span> <span class="n">state</span><span class="p">),</span> <span class="n">value</span><span class="p">,</span>
                <span class="n">state</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">AmplifyForm</span><span class="p">(</span><span class="n">turbogears</span><span class="o">.</span><span class="n">widgets</span><span class="o">.</span><span class="n">Form</span><span class="p">):</span>
    <span class="n">template</span> <span class="o">=</span> <span class="n">my</span><span class="o">.</span><span class="n">templates</span><span class="o">.</span><span class="n">amplifyform</span>
    <span class="n">submit_text</span> <span class="o">=</span> <span class="s">&#39;Enter word to amplify&#39;</span>
    <span class="n">fields</span> <span class="o">=</span> <span class="p">[</span>
            <span class="n">turbogears</span><span class="o">.</span><span class="n">widgets</span><span class="o">.</span><span class="n">TextField</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s">&#39;data&#39;</span><span class="p">,</span>
                    <span class="n">validator</span><span class="o">=</span><span class="n">NotNumberValidator</span><span class="p">())</span>
            <span class="p">]</span>

<span class="n">amplify_form</span> <span class="o">=</span> <span class="n">AmplifyForm</span><span class="p">()</span>

<span class="k">class</span> <span class="nc">mycontroller</span><span class="p">(</span><span class="n">RootController</span><span class="p">):</span>

    <span class="nd">@expose</span><span class="p">(</span><span class="n">template</span><span class="o">=</span><span class="s">&#39;my.templates.errorpage&#39;</span><span class="p">,</span> <span class="n">allow_json</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="k">def</span> <span class="nf">no_numbers</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
        <span class="n">errors</span> <span class="o">=</span> <span class="n">fedora</span><span class="o">.</span><span class="n">tg</span><span class="o">.</span><span class="n">utils</span><span class="o">.</span><span class="n">jsonify_validation_errors</span><span class="p">()</span>
        <span class="k">if</span> <span class="n">errors</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">errors</span>
        <span class="c"># Construct a dict to return the data error message as HTML via</span>
        <span class="c"># the errorpage template</span>
        <span class="k">pass</span>

    <span class="nd">@validate</span><span class="p">(</span><span class="n">form</span><span class="o">=</span><span class="n">amplify_form</span><span class="p">)</span>
    <span class="nd">@error_handler</span><span class="p">(</span><span class="s">&#39;no_numbers&#39;</span><span class="p">)</span>
    <span class="nd">@expose</span><span class="p">(</span><span class="n">template</span><span class="o">=</span><span class="s">&#39;my.templates.amplifypage&#39;</span><span class="p">,</span> <span class="n">allow_json</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="k">def</span> <span class="nf">amplify</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
        <span class="k">return</span> <span class="nb">dict</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="o">.</span><span class="n">upper</span><span class="p">())</span>
</pre></div>
</div>
<p>When a user hits <tt class="docutils literal"><span class="pre">amplify()</span></tt>&#8216;s URL, the validator checks whether <tt class="docutils literal"><span class="pre">data</span></tt> is
a number.  If it is, it redirects to the error_handler, <tt class="docutils literal"><span class="pre">no_numbers()</span></tt>.
<tt class="docutils literal"><span class="pre">no_numbers()</span></tt> will normally return HTML which is fine if we&#8217;re simply
hitting <tt class="docutils literal"><span class="pre">amplify()</span></tt> from a web browser.  If we&#8217;re hitting it from a
<a class="reference internal" href="api.html#fedora.client.BaseClient" title="fedora.client.BaseClient"><tt class="xref py py-class docutils literal"><span class="pre">BaseClient</span></tt></a> app, however, we need it to return
<a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> data instead.  To do that we use <tt class="docutils literal"><span class="pre">jsonify_validation_errors()</span></tt>
which checks whether there was a validation error and whether we need to
return <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> data.  If both of those are true, it returns a dictionary
with the validation errors.  This dictionary is appropriate for returning from
the controller method in response to a <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> request.</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">When defining &#64;error_handler() order of decorators can be important.  The
short story is to always make &#64;validate() and &#64;error_handler() the first
decorators of your method.  The longer version is that this is known to
cause errors with the json request not being honored or skipping identity
checks when the method is its own error handler.</p>
</div>
</div>
</div>
<div class="section" id="expected-methods">
<h2>Expected Methods<a class="headerlink" href="#expected-methods" title="Permalink to this headline">¶</a></h2>
<p>Certain controller methods are necessary in order for
<a class="reference internal" href="api.html#fedora.client.BaseClient" title="fedora.client.BaseClient"><tt class="xref py py-class docutils literal"><span class="pre">BaseClient</span></tt></a> to properly talk to your service.
<a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a> can quickstart an application template for you that sets
most of these variables correctly:</p>
<div class="highlight-python"><pre>$ tg-admin quickstart -i -s -p my my
# edit my/my/controllers.py</pre>
</div>
<div class="section" id="login">
<h3>login()<a class="headerlink" href="#login" title="Permalink to this headline">¶</a></h3>
<p>You need to have a <tt class="docutils literal"><span class="pre">login()</span></tt> method in your application&#8217;s root.  This method
allows <a class="reference internal" href="api.html#fedora.client.BaseClient" title="fedora.client.BaseClient"><tt class="xref py py-class docutils literal"><span class="pre">BaseClient</span></tt></a> to authenticate against your Service:</p>
<div class="highlight-python"><pre>     @expose(template="my.templates.login")
+    @expose(allow_json=True)
     def login(self, forward_url=None, previous_url=None, \*args, \**kw):

         if not identity.current.anonymous \
             and identity.was_login_attempted() \
             and not identity.get_identity_errors():
+            # User is logged in
+            if 'json' == fedora.tg.utils.request_format():
+                return dict(user=identity.current.user)
+            if not forward_url:
+                forward_url = turbogears.url('/')
             raise redirect(forward_url)</pre>
</div>
<div class="section" id="for-non-turbogears-implementors">
<h4>For non-TurboGears Implementors<a class="headerlink" href="#for-non-turbogears-implementors" title="Permalink to this headline">¶</a></h4>
<p>If you are implementing a server in a non-TurboGears framework, note that one
of the ways to reach the <tt class="docutils literal"><span class="pre">login()</span></tt> method is through special parameters
parsed by the <a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a> framework.
<a class="reference internal" href="api.html#fedora.client.BaseClient" title="fedora.client.BaseClient"><tt class="xref py py-class docutils literal"><span class="pre">BaseClient</span></tt></a> uses these parameters instead of invoking
the <tt class="docutils literal"><span class="pre">login()</span></tt> method directly as it saves a round trip when authenticating
to the server.  It will be necessary for you to implement handling of these
parameters (passed via <tt class="docutils literal"><span class="pre">POST</span></tt>) on your application as well.</p>
<p>The parameters are: <tt class="docutils literal"><span class="pre">user_name</span></tt>, <tt class="docutils literal"><span class="pre">password</span></tt>, and <tt class="docutils literal"><span class="pre">login</span></tt>.  When these
three parameters are sent to the server, the server authenticates the user
and records their information before deciding what information to return to
them from the URL.</p>
</div>
</div>
<div class="section" id="logout">
<h3>logout()<a class="headerlink" href="#logout" title="Permalink to this headline">¶</a></h3>
<p>The <tt class="docutils literal"><span class="pre">logout()</span></tt> method is similar to <tt class="docutils literal"><span class="pre">login()</span></tt>.  It also needs to be
modified to allow people to connect to it via <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a>:</p>
<div class="highlight-python"><pre>-    @expose()
+    @expose(allow_json=True)
     def logout(self):
         identity.current.logout()
+        if 'json' in fedora.tg.utils.request_format():
+            return dict()
         raise redirect("/")</pre>
</div>
</div>
</div>
<div class="section" id="csrf-protection">
<h2>CSRF Protection<a class="headerlink" href="#csrf-protection" title="Permalink to this headline">¶</a></h2>
<p>For an overview of CSRF and how to protect <a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a> 1 based
services, look at this document.</p>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="CSRF.html">CSRF Protection</a><ul>
<li class="toctree-l2"><a class="reference internal" href="CSRF.html#how-csrf-works">How CSRF Works</a></li>
<li class="toctree-l2"><a class="reference internal" href="CSRF.html#how-to-prevent-it">How to Prevent It</a></li>
<li class="toctree-l2"><a class="reference internal" href="CSRF.html#summary-of-changes-per-app">Summary of Changes Per App</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div class="section" id="using-sabase">
<span id="id8"></span><h2>Using SABase<a class="headerlink" href="#using-sabase" title="Permalink to this headline">¶</a></h2>
<p><tt class="docutils literal"><span class="pre">fedora.tg.json</span></tt> contains several functions that help to convert <a class="reference external" href="http://www.sqlalchemy.org">SQLAlchemy</a>
objects into <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a>.  For the most part, these do their work behind the
scenes.  The <tt class="docutils literal"><span class="pre">SABase</span></tt> object, however, is one that you might need to take an
active role in using.</p>
<p>When you return an <a class="reference external" href="http://www.sqlalchemy.org">SQLAlchemy</a> object in a controller to a template, the
template is able to access any of the relations mapped to it.  So, instead of
having to construct a list of people records from a table and
the the list of groups that each of them are in you can pass in the list of
people and let your template reference the relation properties to get the
groups.  This is extremely convenient for templates but has a negative effect
when returning <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a>. Namely, the default methods for marshaling
<a class="reference external" href="http://www.sqlalchemy.org">SQLAlchemy</a> objects to <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> only return the attributes of the object,
not the relations that are linked to it.  So you can easily run into a
situation where someone querying the <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> data for a page will not
have all the information that a template has access to.</p>
<p>SABase fixes this by allowing you to specify relations that your
<a class="reference external" href="http://www.sqlalchemy.org">SQLAlchemy</a> backed objects should marshal as <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> data.</p>
<p>Further information on SABase can be found in the API documentation:</p>
<div class="highlight-python"><pre>pydoc fedora.tg.json</pre>
</div>
<div class="section" id="example">
<h3>Example<a class="headerlink" href="#example" title="Permalink to this headline">¶</a></h3>
<p>SABase is a base class that you can use when defining objects
in your project&#8217;s model.  So the first step is defining the classes in your
model to inherit from SABase:</p>
<div class="highlight-python"><pre>from fedora.tg.json import SABase
from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
from turbogears.database import metadata, mapper

class Person(SABase):
    pass
PersonTable = Table('person', metadata
    Column('name', String, primary_key=True),
    )

class Address(SABase):
    pass
AddressTable = Table (
    Column('id', Integer, primary_key=True),
    Column('street', string),
    Column('person_id', Integer, ForeignKey('person.name')
    )

mapper(PersonTable, Person)
mapper(AddressTable, Address, properties = {
    person: relation(Person, backref = 'addresses'),
})</pre>
</div>
<p>The next step is to tell SABase which properties should be copied (this
allows you to omit large trees of objects when you only need the data from
a few of them):</p>
<div class="highlight-python"><pre>@expose('my.templates.about_me')
@expose(allow_json=True)
def my_info(self):
    person = Person.query.filter_by(name='Myself').one()
    person.jsonProps = {'Person': ['addresses']}
    return dict(myself=person}</pre>
</div>
<p>Now, when someone requests <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> data from my_info, they should get
back a record for person that includes a property addresses.  Addresses will
be a list of address records associated with the person.</p>
</div>
<div class="section" id="how-it-works">
<h3>How it Works<a class="headerlink" href="#how-it-works" title="Permalink to this headline">¶</a></h3>
<p>SABase adds a special <a class="reference internal" href="#id9">__json__()</a> method to the class.  By default, this
method returns a dict with all of the attributes that are backed by fields in
the database.</p>
<p>Adding entries to jsonProps adds the values for those properties to the
returned dict as well.  If you need to override the <a class="reference internal" href="#id9">__json__()</a> method in
your class you probably want to call SABase&#8217;s <a class="reference internal" href="#id9">__json__()</a> unless you know
that neither you nor any future subclasses will need it.</p>
</div>
</div>
<div class="section" id="using-json">
<span id="id9"></span><h2>Using __json__()<a class="headerlink" href="#using-json" title="Permalink to this headline">¶</a></h2>
<p>Sometimes you need to return an object that isn&#8217;t a basic python type (list,
tuple, dict, number. string, etc).  When that occurs, <a class="reference external" href="http://undefined.org/python/#simplejson">simplejson</a> won&#8217;t know
how to marshal the data into <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> until you write own method to
transform the values.  If this method is named __json__(), <a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a>
will automatically perform the conversion when you return the object.</p>
<p>Example:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">MyObject</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">_init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">someNumber</span> <span class="o">=</span> <span class="n">number</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">cached</span> <span class="o">=</span> <span class="bp">None</span>

    <span class="k">def</span> <span class="nf">_calc_data</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">cached</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">cached</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">someNumber</span> <span class="o">*</span> <span class="mi">2</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">cached</span>

    <span class="n">twiceData</span> <span class="o">=</span> <span class="nb">property</span><span class="p">(</span><span class="n">_calc_data</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">__json__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="p">{</span><span class="s">&#39;someNumber&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">someNumber</span><span class="p">,</span> <span class="s">&#39;twiceData&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">twiceData</span><span class="p">}</span>
</pre></div>
</div>
<p>In this class, you have a variable and a property.  If you were to return it
from a controller method without defining the __json__() method,
<a class="reference internal" href="glossary.html#term-turbogears"><em class="xref std std-term">TurboGears</em></a> would give you an error that it was unable to adapt the
object to <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a>.  The <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a> method transforms the object into a
dict with sensibly named values for the variable and property so that
simplejson is able to marshal the data to <a class="reference internal" href="glossary.html#term-json"><em class="xref std std-term">JSON</em></a>.  Note that you will
often have to choose between space (more data takes more bandwidth to deliver
to the end user) and completeness (you need to return enough data so the
client isn&#8217;t looking for another method that can complete its needs) when
returning data.</p>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
  <h3><a href="index.html">Table Of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Fedora Services</a><ul>
<li><a class="reference internal" href="#module-fedora.tg">TurboGears and fedora.tg</a></li>
<li><a class="reference internal" href="#module-fedora.tg.utils">Controllers</a></li>
<li><a class="reference internal" href="#urls-as-api">URLs as API</a><ul>
<li><a class="reference internal" href="#selecting-json-output">Selecting JSON Output</a></li>
<li><a class="reference internal" href="#why-two-formats-from-a-single-url">Why Two Formats from a Single URL?</a><ul>
<li><a class="reference internal" href="#benefits-of-one-method-handling-multiple-formats">Benefits of One Method Handling Multiple Formats</a></li>
<li><a class="reference internal" href="#benefits-of-multiple-methods-for-each-format">Benefits of Multiple Methods for Each Format</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#return-values">Return Values</a><ul>
<li><a class="reference internal" href="#marshaling">Marshaling</a></li>
<li><a class="reference internal" href="#unicode">Unicode</a></li>
<li><a class="reference internal" href="#error-handling">Error Handling</a><ul>
<li><a class="reference internal" href="#exc">exc</a></li>
<li><a class="reference internal" href="#tg-flash">tg_flash</a></li>
<li><a class="reference internal" href="#authentication-errors">Authentication Errors</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#performing-different-actions-when-returning-json">Performing Different Actions when Returning JSON</a><ul>
<li><a class="reference internal" href="#redirects">Redirects</a></li>
<li><a class="reference internal" href="#tg-template">tg_template</a></li>
<li><a class="reference internal" href="#validators">Validators</a></li>
</ul>
</li>
<li><a class="reference internal" href="#expected-methods">Expected Methods</a><ul>
<li><a class="reference internal" href="#login">login()</a><ul>
<li><a class="reference internal" href="#for-non-turbogears-implementors">For non-TurboGears Implementors</a></li>
</ul>
</li>
<li><a class="reference internal" href="#logout">logout()</a></li>
</ul>
</li>
<li><a class="reference internal" href="#csrf-protection">CSRF Protection</a><ul>
</ul>
</li>
<li><a class="reference internal" href="#using-sabase">Using SABase</a><ul>
<li><a class="reference internal" href="#example">Example</a></li>
<li><a class="reference internal" href="#how-it-works">How it Works</a></li>
</ul>
</li>
<li><a class="reference internal" href="#using-json">Using __json__()</a></li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="existing.html"
                        title="previous chapter">Existing Services</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="CSRF.html"
                        title="next chapter">CSRF Protection</a></p>
  <h3>This Page</h3>
  <ul class="this-page-menu">
    <li><a href="_sources/service.txt"
           rel="nofollow">Show Source</a></li>
  </ul>
<div id="searchbox" style="display: none">
  <h3>Quick search</h3>
    <form class="search" action="search.html" method="get">
      <input type="text" name="q" size="18" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    <p class="searchtip" style="font-size: 90%">
    Enter search terms or a module, class or function name.
    </p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="CSRF.html" title="CSRF Protection"
             >next</a> |</li>
        <li class="right" >
          <a href="existing.html" title="Existing Services"
             >previous</a> |</li>
        <li><a href="index.html">python-fedora v0.3.25.1 documentation</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
        &copy; Copyright 2007-2011 Red Hat, Inc..
      Last updated on Nov 02, 2011.
      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
    </div>
  </body>
</html>