Update documentation

This commit is contained in:
Alexis Metaireau 2011-12-07 09:19:11 -01:00
parent d7bf092ae3
commit 2a2a68395b
4 changed files with 332 additions and 40 deletions

View file

@ -14,12 +14,13 @@ it is easily pluggable with validations frameworks, such as Collander.</p>
<span class="k">def</span> <span class="nf">is_awesome</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="s">'awesome'</span> <span class="ow">in</span> <span class="n">request</span><span class="o">.</span><span class="n">GET</span><span class="p">:</span>
<span class="n">request</span><span class="o">.</span><span class="n">errors</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s">'body'</span><span class="p">,</span> <span class="s">'awesome'</span><span class="p">,</span> <span class="s">'You lack awesomeness!'</span><span class="p">)</span>
<span class="n">request</span><span class="o">.</span><span class="n">errors</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s">'body'</span><span class="p">,</span> <span class="s">'awesome'</span><span class="p">,</span>
<span class="s">'the awesome parameter is required'</span><span class="p">)</span>
<span class="nd">@service.get</span><span class="p">(</span><span class="n">validator</span><span class="o">=</span><span class="p">(</span><span class="n">is_awesome</span><span class="p">))</span>
<span class="nd">@service.get</span><span class="p">(</span><span class="n">validator</span><span class="o">=</span><span class="n">is_awesome</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">get1</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
<span class="k">return</span> <span class="p">{</span><span class="s">"test"</span><span class="p">:</span> <span class="s">"succeeded"</span><span class="p">}</span>
<span class="k">return</span> <span class="p">{</span><span class="s">"test"</span><span class="p">:</span> <span class="s">"yay!"</span><span class="p">}</span>
</pre></div>
<p>All the errors collected during the validation process, or after, are collected
before returning the request. If any, a error 400 is fired up, with the list of
@ -30,19 +31,91 @@ formats in the future)</p>
<p><strong>location</strong> is where the error arised. It can either be "body", "query", "headers"
or "path". <strong>name</strong> is the name of the variable causing problem, if any, and
<strong>description</strong> contains a more detailled message.</p>
<p>Here is an example of a malformed request:</p>
<p>Let's run this simple service, with <cite>bin/paster serve</cite> and send some queries to
it:</p>
<div class="highlight"><pre>$ curl -v http://127.0.0.1:5000/service
> GET /service HTTP/1.1
> Host: 127.0.0.1:5000
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 400 Bad Request
< Content-Type: application/json; charset=UTF-8
[{"location": "body", "name": "awesome", "description": "You lack awesomeness!"}
</pre></div>
<p>I've removed the extra clutter from the curl's output, but you got the general idea.</p>
<p>The content returned is in JSON, and I know exactly what I have to do: add an
"awesome" parameter in my query. Let's do it again:</p>
<pre class="literal-block">
$ # run a demo app
$ curl http://127.0.0.1:5000/service?awesome=yeah
{"test": "yay!"}
</pre>
<p>To describe a web service in <em>cornice</em>, you have to write something like this</p>
<div class="system-message">
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">./content/mozilla/introducing-cornice.rst</tt>, line 54)</p>
<p>Content block expected for the "code-block" directive; none found.</p>
<p>Validators can also attach extra information about validations to the request,
using <cite>request.validated</cite>. It is a standard dict automatically attached to the
requests.</p>
<p>For instance, in our validator, we can chose to validate the parameter passed
and use it in the body of the webservice:</p>
<div class="highlight"><pre><span class="n">service</span> <span class="o">=</span> <span class="n">Service</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s">"service"</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="s">"/service"</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">is_awesome</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="s">'awesome'</span> <span class="ow">in</span> <span class="n">request</span><span class="o">.</span><span class="n">GET</span><span class="p">:</span>
<span class="n">request</span><span class="o">.</span><span class="n">errors</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s">'body'</span><span class="p">,</span> <span class="s">'awesome'</span><span class="p">,</span>
<span class="s">'the awesome parameter is required'</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">request</span><span class="o">.</span><span class="n">validated</span><span class="p">[</span><span class="s">'awesome'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'awesome '</span> <span class="o">+</span> <span class="n">request</span><span class="o">.</span><span class="n">GET</span><span class="p">[</span><span class="s">'awesome'</span><span class="p">]</span>
<span class="nd">@service.get</span><span class="p">(</span><span class="n">validator</span><span class="o">=</span><span class="n">is_awesome</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">get1</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
<span class="k">return</span> <span class="p">{</span><span class="s">"test"</span><span class="p">:</span> <span class="n">request</span><span class="o">.</span><span class="n">validated</span><span class="p">[</span><span class="s">'awesome'</span><span class="p">]}</span>
</pre></div>
<pre class="literal-block">
.. code-block:: python
curl http://127.0.0.1:5000/service?awesome=yeah
{"test": "awesome yeah"}
</pre>
</div>
<div class="section" id="dealing-with-accept-headers">
<h2>Dealing with "Accept" headers</h2>
<p>The HTTP spec defines a <strong>Accept</strong> header the client can send so the response
is encoded the right way. A resource, available at an URL, can be available in
different formats. This is especially true for web services.</p>
<p>Cornice can help you to deal with this. The services you define can tell which
content-types they can deal with, and this will be checked against the
<strong>Accept</strong> headers sent by the client.</p>
<p>Let's refine a bit our previous example, by specifying which content-types are
supported, using the <cite>accept</cite> parameter:</p>
<div class="system-message">
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">./content/mozilla/introducing-cornice.rst</tt>, line 117)</p>
<p>Error in "code-block" directive:
1 argument(s) required, 0 supplied.</p>
<pre class="literal-block">
.. code-block::
@service.get(validator=is_awesome, accept=("application/json", "text/json"))
def get1(request):
return {"test": "yay!"}
</pre>
</div>
<p>Now, if you specifically ask for XML, for instance, cornice will throw a 406
with the list of accepted content-types:</p>
<pre class="literal-block">
$ curl -vH "Accept: application/xml" http://127.0.0.1:5000/service
> GET /service HTTP/1.1
> Host: 127.0.0.1:5000
> Accept: application/xml
>
< HTTP/1.0 406 Not Acceptable
< Content-Type: application/json; charset=UTF-8
< Content-Length: 33
<
["application/json", "text/json"]
</pre>
</div>
<div class="section" id="building-your-documentation-automatically">
<h2>Building your documentation automatically</h2>
<p>XXX</p>
</div>
</summary></entry><entry><title>How are you handling your shared expenses?</title><link href="http://blog.notmyidea.org/how-are-you-handling-your-shared-expenses.html" rel="alternate"></link><updated>2011-10-15T00:00:00+02:00</updated><author><name>Alexis Métaireau</name></author><id>tag:blog.notmyidea.org,2011-10-15:/how-are-you-handling-your-shared-expenses.html/</id><summary type="html">&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; We're kick-starting a new application to manage your shared
expenses. Have a look at &lt;a class="reference external" href="http://ihatemoney.notmyidea.org"&gt;http://ihatemoney.notmyidea.org&lt;/a&gt;&lt;/p&gt;

View file

@ -14,12 +14,13 @@ it is easily pluggable with validations frameworks, such as Collander.&lt;/p&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_awesome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;awesome&amp;#39;&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;awesome&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;You lack awesomeness!&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;awesome&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s"&gt;&amp;#39;the awesome parameter is required&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@service.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is_awesome&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nd"&gt;@service.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;is_awesome&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;succeeded&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;yay!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;All the errors collected during the validation process, or after, are collected
before returning the request. If any, a error 400 is fired up, with the list of
@ -30,19 +31,91 @@ formats in the future)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;location&lt;/strong&gt; is where the error arised. It can either be &amp;quot;body&amp;quot;, &amp;quot;query&amp;quot;, &amp;quot;headers&amp;quot;
or &amp;quot;path&amp;quot;. &lt;strong&gt;name&lt;/strong&gt; is the name of the variable causing problem, if any, and
&lt;strong&gt;description&lt;/strong&gt; contains a more detailled message.&lt;/p&gt;
&lt;p&gt;Here is an example of a malformed request:&lt;/p&gt;
&lt;p&gt;Let's run this simple service, with &lt;cite&gt;bin/paster serve&lt;/cite&gt; and send some queries to
it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;$ curl -v http://127.0.0.1:5000/service
&amp;gt; GET /service HTTP/1.1
&amp;gt; Host: 127.0.0.1:5000
&amp;gt; Accept: */*
&amp;gt;
* HTTP 1.0, assume close after body
&amp;lt; HTTP/1.0 400 Bad Request
&amp;lt; Content-Type: application/json; charset=UTF-8
[{&amp;quot;location&amp;quot;: &amp;quot;body&amp;quot;, &amp;quot;name&amp;quot;: &amp;quot;awesome&amp;quot;, &amp;quot;description&amp;quot;: &amp;quot;You lack awesomeness!&amp;quot;}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I've removed the extra clutter from the curl's output, but you got the general idea.&lt;/p&gt;
&lt;p&gt;The content returned is in JSON, and I know exactly what I have to do: add an
&amp;quot;awesome&amp;quot; parameter in my query. Let's do it again:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ # run a demo app
$ curl http://127.0.0.1:5000/service?awesome=yeah
{&amp;quot;test&amp;quot;: &amp;quot;yay!&amp;quot;}
&lt;/pre&gt;
&lt;p&gt;To describe a web service in &lt;em&gt;cornice&lt;/em&gt;, you have to write something like this&lt;/p&gt;
&lt;div class="system-message"&gt;
&lt;p class="system-message-title"&gt;System Message: ERROR/3 (&lt;tt class="docutils"&gt;./content/mozilla/introducing-cornice.rst&lt;/tt&gt;, line 54)&lt;/p&gt;
&lt;p&gt;Content block expected for the &amp;quot;code-block&amp;quot; directive; none found.&lt;/p&gt;
&lt;p&gt;Validators can also attach extra information about validations to the request,
using &lt;cite&gt;request.validated&lt;/cite&gt;. It is a standard dict automatically attached to the
requests.&lt;/p&gt;
&lt;p&gt;For instance, in our validator, we can chose to validate the parameter passed
and use it in the body of the webservice:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;service&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/service&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_awesome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;awesome&amp;#39;&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;awesome&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s"&gt;&amp;#39;the awesome parameter is required&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;awesome&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;awesome &amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;awesome&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nd"&gt;@service.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;is_awesome&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;awesome&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;pre class="literal-block"&gt;
.. code-block:: python
curl http://127.0.0.1:5000/service?awesome=yeah
{&amp;quot;test&amp;quot;: &amp;quot;awesome yeah&amp;quot;}
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="dealing-with-accept-headers"&gt;
&lt;h2&gt;Dealing with &amp;quot;Accept&amp;quot; headers&lt;/h2&gt;
&lt;p&gt;The HTTP spec defines a &lt;strong&gt;Accept&lt;/strong&gt; header the client can send so the response
is encoded the right way. A resource, available at an URL, can be available in
different formats. This is especially true for web services.&lt;/p&gt;
&lt;p&gt;Cornice can help you to deal with this. The services you define can tell which
content-types they can deal with, and this will be checked against the
&lt;strong&gt;Accept&lt;/strong&gt; headers sent by the client.&lt;/p&gt;
&lt;p&gt;Let's refine a bit our previous example, by specifying which content-types are
supported, using the &lt;cite&gt;accept&lt;/cite&gt; parameter:&lt;/p&gt;
&lt;div class="system-message"&gt;
&lt;p class="system-message-title"&gt;System Message: ERROR/3 (&lt;tt class="docutils"&gt;./content/mozilla/introducing-cornice.rst&lt;/tt&gt;, line 117)&lt;/p&gt;
&lt;p&gt;Error in &amp;quot;code-block&amp;quot; directive:
1 argument(s) required, 0 supplied.&lt;/p&gt;
&lt;pre class="literal-block"&gt;
.. code-block::
&amp;#64;service.get(validator=is_awesome, accept=(&amp;quot;application/json&amp;quot;, &amp;quot;text/json&amp;quot;))
def get1(request):
return {&amp;quot;test&amp;quot;: &amp;quot;yay!&amp;quot;}
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now, if you specifically ask for XML, for instance, cornice will throw a 406
with the list of accepted content-types:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ curl -vH &amp;quot;Accept: application/xml&amp;quot; http://127.0.0.1:5000/service
&amp;gt; GET /service HTTP/1.1
&amp;gt; Host: 127.0.0.1:5000
&amp;gt; Accept: application/xml
&amp;gt;
&amp;lt; HTTP/1.0 406 Not Acceptable
&amp;lt; Content-Type: application/json; charset=UTF-8
&amp;lt; Content-Length: 33
&amp;lt;
[&amp;quot;application/json&amp;quot;, &amp;quot;text/json&amp;quot;]
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="building-your-documentation-automatically"&gt;
&lt;h2&gt;Building your documentation automatically&lt;/h2&gt;
&lt;p&gt;XXX&lt;/p&gt;
&lt;/div&gt;
</summary></entry><entry><title>Quels usages pour l'informatique ?</title><link href="http://blog.notmyidea.org/quels-usages-pour-linformatique-fr.html" rel="alternate"></link><updated>2011-12-01T00:00:00+01:00</updated><author><name>Alexis Métaireau</name></author><id>tag:blog.notmyidea.org,2011-12-01:/quels-usages-pour-linformatique-fr.html/</id><summary type="html">&lt;p&gt;Quand on termine ses études, on s'en pose un tas, des questions. Sur le métier
que l'on veut faire, sur ce que ça signifie, sur le sens et la valeur du

View file

@ -14,12 +14,13 @@ it is easily pluggable with validations frameworks, such as Collander.&lt;/p&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_awesome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;awesome&amp;#39;&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;awesome&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;You lack awesomeness!&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;awesome&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s"&gt;&amp;#39;the awesome parameter is required&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@service.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is_awesome&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nd"&gt;@service.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;is_awesome&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;succeeded&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;yay!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;All the errors collected during the validation process, or after, are collected
before returning the request. If any, a error 400 is fired up, with the list of
@ -30,18 +31,90 @@ formats in the future)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;location&lt;/strong&gt; is where the error arised. It can either be &amp;quot;body&amp;quot;, &amp;quot;query&amp;quot;, &amp;quot;headers&amp;quot;
or &amp;quot;path&amp;quot;. &lt;strong&gt;name&lt;/strong&gt; is the name of the variable causing problem, if any, and
&lt;strong&gt;description&lt;/strong&gt; contains a more detailled message.&lt;/p&gt;
&lt;p&gt;Here is an example of a malformed request:&lt;/p&gt;
&lt;p&gt;Let's run this simple service, with &lt;cite&gt;bin/paster serve&lt;/cite&gt; and send some queries to
it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;$ curl -v http://127.0.0.1:5000/service
&amp;gt; GET /service HTTP/1.1
&amp;gt; Host: 127.0.0.1:5000
&amp;gt; Accept: */*
&amp;gt;
* HTTP 1.0, assume close after body
&amp;lt; HTTP/1.0 400 Bad Request
&amp;lt; Content-Type: application/json; charset=UTF-8
[{&amp;quot;location&amp;quot;: &amp;quot;body&amp;quot;, &amp;quot;name&amp;quot;: &amp;quot;awesome&amp;quot;, &amp;quot;description&amp;quot;: &amp;quot;You lack awesomeness!&amp;quot;}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I've removed the extra clutter from the curl's output, but you got the general idea.&lt;/p&gt;
&lt;p&gt;The content returned is in JSON, and I know exactly what I have to do: add an
&amp;quot;awesome&amp;quot; parameter in my query. Let's do it again:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ # run a demo app
$ curl http://127.0.0.1:5000/service?awesome=yeah
{&amp;quot;test&amp;quot;: &amp;quot;yay!&amp;quot;}
&lt;/pre&gt;
&lt;p&gt;To describe a web service in &lt;em&gt;cornice&lt;/em&gt;, you have to write something like this&lt;/p&gt;
&lt;div class="system-message"&gt;
&lt;p class="system-message-title"&gt;System Message: ERROR/3 (&lt;tt class="docutils"&gt;./content/mozilla/introducing-cornice.rst&lt;/tt&gt;, line 54)&lt;/p&gt;
&lt;p&gt;Content block expected for the &amp;quot;code-block&amp;quot; directive; none found.&lt;/p&gt;
&lt;p&gt;Validators can also attach extra information about validations to the request,
using &lt;cite&gt;request.validated&lt;/cite&gt;. It is a standard dict automatically attached to the
requests.&lt;/p&gt;
&lt;p&gt;For instance, in our validator, we can chose to validate the parameter passed
and use it in the body of the webservice:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;service&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/service&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_awesome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;awesome&amp;#39;&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;awesome&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s"&gt;&amp;#39;the awesome parameter is required&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;awesome&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;awesome &amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;awesome&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nd"&gt;@service.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;is_awesome&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;awesome&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;pre class="literal-block"&gt;
.. code-block:: python
curl http://127.0.0.1:5000/service?awesome=yeah
{&amp;quot;test&amp;quot;: &amp;quot;awesome yeah&amp;quot;}
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="dealing-with-accept-headers"&gt;
&lt;h2&gt;Dealing with &amp;quot;Accept&amp;quot; headers&lt;/h2&gt;
&lt;p&gt;The HTTP spec defines a &lt;strong&gt;Accept&lt;/strong&gt; header the client can send so the response
is encoded the right way. A resource, available at an URL, can be available in
different formats. This is especially true for web services.&lt;/p&gt;
&lt;p&gt;Cornice can help you to deal with this. The services you define can tell which
content-types they can deal with, and this will be checked against the
&lt;strong&gt;Accept&lt;/strong&gt; headers sent by the client.&lt;/p&gt;
&lt;p&gt;Let's refine a bit our previous example, by specifying which content-types are
supported, using the &lt;cite&gt;accept&lt;/cite&gt; parameter:&lt;/p&gt;
&lt;div class="system-message"&gt;
&lt;p class="system-message-title"&gt;System Message: ERROR/3 (&lt;tt class="docutils"&gt;./content/mozilla/introducing-cornice.rst&lt;/tt&gt;, line 117)&lt;/p&gt;
&lt;p&gt;Error in &amp;quot;code-block&amp;quot; directive:
1 argument(s) required, 0 supplied.&lt;/p&gt;
&lt;pre class="literal-block"&gt;
.. code-block::
&amp;#64;service.get(validator=is_awesome, accept=(&amp;quot;application/json&amp;quot;, &amp;quot;text/json&amp;quot;))
def get1(request):
return {&amp;quot;test&amp;quot;: &amp;quot;yay!&amp;quot;}
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now, if you specifically ask for XML, for instance, cornice will throw a 406
with the list of accepted content-types:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ curl -vH &amp;quot;Accept: application/xml&amp;quot; http://127.0.0.1:5000/service
&amp;gt; GET /service HTTP/1.1
&amp;gt; Host: 127.0.0.1:5000
&amp;gt; Accept: application/xml
&amp;gt;
&amp;lt; HTTP/1.0 406 Not Acceptable
&amp;lt; Content-Type: application/json; charset=UTF-8
&amp;lt; Content-Length: 33
&amp;lt;
[&amp;quot;application/json&amp;quot;, &amp;quot;text/json&amp;quot;]
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="building-your-documentation-automatically"&gt;
&lt;h2&gt;Building your documentation automatically&lt;/h2&gt;
&lt;p&gt;XXX&lt;/p&gt;
&lt;/div&gt;
</summary></entry></feed>

View file

@ -29,12 +29,13 @@ it is easily pluggable with validations frameworks, such as Collander.</p>
<span class="k">def</span> <span class="nf">is_awesome</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="s">&#39;awesome&#39;</span> <span class="ow">in</span> <span class="n">request</span><span class="o">.</span><span class="n">GET</span><span class="p">:</span>
<span class="n">request</span><span class="o">.</span><span class="n">errors</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s">&#39;body&#39;</span><span class="p">,</span> <span class="s">&#39;awesome&#39;</span><span class="p">,</span> <span class="s">&#39;You lack awesomeness!&#39;</span><span class="p">)</span>
<span class="n">request</span><span class="o">.</span><span class="n">errors</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s">&#39;body&#39;</span><span class="p">,</span> <span class="s">&#39;awesome&#39;</span><span class="p">,</span>
<span class="s">&#39;the awesome parameter is required&#39;</span><span class="p">)</span>
<span class="nd">@service.get</span><span class="p">(</span><span class="n">validator</span><span class="o">=</span><span class="p">(</span><span class="n">is_awesome</span><span class="p">))</span>
<span class="nd">@service.get</span><span class="p">(</span><span class="n">validator</span><span class="o">=</span><span class="n">is_awesome</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">get1</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
<span class="k">return</span> <span class="p">{</span><span class="s">&quot;test&quot;</span><span class="p">:</span> <span class="s">&quot;succeeded&quot;</span><span class="p">}</span>
<span class="k">return</span> <span class="p">{</span><span class="s">&quot;test&quot;</span><span class="p">:</span> <span class="s">&quot;yay!&quot;</span><span class="p">}</span>
</pre></div>
<p>All the errors collected during the validation process, or after, are collected
before returning the request. If any, a error 400 is fired up, with the list of
@ -45,19 +46,91 @@ formats in the future)</p>
<p><strong>location</strong> is where the error arised. It can either be &quot;body&quot;, &quot;query&quot;, &quot;headers&quot;
or &quot;path&quot;. <strong>name</strong> is the name of the variable causing problem, if any, and
<strong>description</strong> contains a more detailled message.</p>
<p>Here is an example of a malformed request:</p>
<p>Let's run this simple service, with <cite>bin/paster serve</cite> and send some queries to
it:</p>
<div class="highlight"><pre>$ curl -v http://127.0.0.1:5000/service
&gt; GET /service HTTP/1.1
&gt; Host: 127.0.0.1:5000
&gt; Accept: */*
&gt;
* HTTP 1.0, assume close after body
&lt; HTTP/1.0 400 Bad Request
&lt; Content-Type: application/json; charset=UTF-8
[{&quot;location&quot;: &quot;body&quot;, &quot;name&quot;: &quot;awesome&quot;, &quot;description&quot;: &quot;You lack awesomeness!&quot;}
</pre></div>
<p>I've removed the extra clutter from the curl's output, but you got the general idea.</p>
<p>The content returned is in JSON, and I know exactly what I have to do: add an
&quot;awesome&quot; parameter in my query. Let's do it again:</p>
<pre class="literal-block">
$ # run a demo app
$ curl http://127.0.0.1:5000/service?awesome=yeah
{&quot;test&quot;: &quot;yay!&quot;}
</pre>
<p>To describe a web service in <em>cornice</em>, you have to write something like this</p>
<div class="system-message">
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">./content/mozilla/introducing-cornice.rst</tt>, line 54)</p>
<p>Content block expected for the &quot;code-block&quot; directive; none found.</p>
<p>Validators can also attach extra information about validations to the request,
using <cite>request.validated</cite>. It is a standard dict automatically attached to the
requests.</p>
<p>For instance, in our validator, we can chose to validate the parameter passed
and use it in the body of the webservice:</p>
<div class="highlight"><pre><span class="n">service</span> <span class="o">=</span> <span class="n">Service</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s">&quot;service&quot;</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="s">&quot;/service&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">is_awesome</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="s">&#39;awesome&#39;</span> <span class="ow">in</span> <span class="n">request</span><span class="o">.</span><span class="n">GET</span><span class="p">:</span>
<span class="n">request</span><span class="o">.</span><span class="n">errors</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s">&#39;body&#39;</span><span class="p">,</span> <span class="s">&#39;awesome&#39;</span><span class="p">,</span>
<span class="s">&#39;the awesome parameter is required&#39;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">request</span><span class="o">.</span><span class="n">validated</span><span class="p">[</span><span class="s">&#39;awesome&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&#39;awesome &#39;</span> <span class="o">+</span> <span class="n">request</span><span class="o">.</span><span class="n">GET</span><span class="p">[</span><span class="s">&#39;awesome&#39;</span><span class="p">]</span>
<span class="nd">@service.get</span><span class="p">(</span><span class="n">validator</span><span class="o">=</span><span class="n">is_awesome</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">get1</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
<span class="k">return</span> <span class="p">{</span><span class="s">&quot;test&quot;</span><span class="p">:</span> <span class="n">request</span><span class="o">.</span><span class="n">validated</span><span class="p">[</span><span class="s">&#39;awesome&#39;</span><span class="p">]}</span>
</pre></div>
<pre class="literal-block">
.. code-block:: python
curl http://127.0.0.1:5000/service?awesome=yeah
{&quot;test&quot;: &quot;awesome yeah&quot;}
</pre>
</div>
<div class="section" id="dealing-with-accept-headers">
<h2>Dealing with &quot;Accept&quot; headers</h2>
<p>The HTTP spec defines a <strong>Accept</strong> header the client can send so the response
is encoded the right way. A resource, available at an URL, can be available in
different formats. This is especially true for web services.</p>
<p>Cornice can help you to deal with this. The services you define can tell which
content-types they can deal with, and this will be checked against the
<strong>Accept</strong> headers sent by the client.</p>
<p>Let's refine a bit our previous example, by specifying which content-types are
supported, using the <cite>accept</cite> parameter:</p>
<div class="system-message">
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">./content/mozilla/introducing-cornice.rst</tt>, line 117)</p>
<p>Error in &quot;code-block&quot; directive:
1 argument(s) required, 0 supplied.</p>
<pre class="literal-block">
.. code-block::
&#64;service.get(validator=is_awesome, accept=(&quot;application/json&quot;, &quot;text/json&quot;))
def get1(request):
return {&quot;test&quot;: &quot;yay!&quot;}
</pre>
</div>
<p>Now, if you specifically ask for XML, for instance, cornice will throw a 406
with the list of accepted content-types:</p>
<pre class="literal-block">
$ curl -vH &quot;Accept: application/xml&quot; http://127.0.0.1:5000/service
&gt; GET /service HTTP/1.1
&gt; Host: 127.0.0.1:5000
&gt; Accept: application/xml
&gt;
&lt; HTTP/1.0 406 Not Acceptable
&lt; Content-Type: application/json; charset=UTF-8
&lt; Content-Length: 33
&lt;
[&quot;application/json&quot;, &quot;text/json&quot;]
</pre>
</div>
<div class="section" id="building-your-documentation-automatically">
<h2>Building your documentation automatically</h2>
<p>XXX</p>
</div>