Commit 10885304 authored by Jacek Furmankiewicz's avatar Jacek Furmankiewicz

added better docs on how to return responses from REST services

parent c184036a
......@@ -5,6 +5,6 @@
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">python</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
<path>/corepost</path>
<path>/corepost-pages</path>
</pydev_pathproperty>
</pydev_project>
#Fri Apr 20 15:05:37 EDT 2012
eclipse.preferences.version=1
encoding//doc/source/conf.py=utf-8
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 85f542c5812a83c65e62d87283293d45
config: ba4b37ede2c9ab03178a68cf4d460b1c
tags: fbb0d17656682115ca4d033fb2f83ba1
......@@ -18,9 +18,10 @@ Features
url_routing
argument_parsing
arguments
http_codes
responses
content_types
modules
filters
http_codes
async
modules
Returning responses
===================
There are a number of ways in which you can return a response from a REST service
String
------
You can simply return a plain text String. CorePost will return the appropriate HTTP code for you::
@route("/",Http.GET)
def root(self,request,**kwargs):
return "Hello"
Dictionaries, lists or classes
------------------------------
You can return straight dictionaries::
@route("/",Http.GET)
def root(self,request,**kwargs):
return {"test":"test"}
or lists::
@route("/",Http.GET)
def root(self,request,**kwargs):
return [{"test":"test"},{"test":"test2"}]
or classes::
@route("/",Http.GET)
def root(self,request,**kwargs):
return SomeClass()
CorePost will serialize each of them to the appropriate content type (JSON,YAML or XML), depending on what the caller can accept.
Response objects
----------------
This option gives you the most control, as you can explicitly specify the response content, headers and HTTP code.
You need to return an instance of *corepost.Response* object::
class Response:
"""
Custom response object, can be returned instead of raw string response
"""
def __init__(self,code=200,entity=None,headers={}):
pass
Example::
@route("/",Http.POST)
def post(self,request,customerId,addressId,streetNumber,streetName,stateCode,countryCode):
c = DB.getCustomer(customerId)
address = CustomerAddress(streetNumber,streetName,stateCode,countryCode)
c.addresses[addressId] = address
return Response(201)
......@@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Argument parsing &mdash; CorePost 0.0.14 documentation</title>
<title>Argument parsing &mdash; CorePost 0.0.16 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
......@@ -16,7 +16,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.0.14',
VERSION: '0.0.16',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
......@@ -25,7 +25,7 @@
<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="top" title="CorePost 0.0.14 documentation" href="index.html" />
<link rel="top" title="CorePost 0.0.16 documentation" href="index.html" />
<link rel="next" title="Argument validation" href="arguments.html" />
<link rel="prev" title="URL Routing" href="url_routing.html" />
</head>
......@@ -42,7 +42,7 @@
<li class="right" >
<a href="url_routing.html" title="URL Routing"
accesskey="P">previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
......@@ -175,7 +175,7 @@ for you without any additional effort.</p>
<li class="right" >
<a href="url_routing.html" title="URL Routing"
>previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
......
......@@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Argument validation &mdash; CorePost 0.0.14 documentation</title>
<title>Argument validation &mdash; CorePost 0.0.16 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
......@@ -16,7 +16,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.0.14',
VERSION: '0.0.16',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
......@@ -25,8 +25,8 @@
<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="top" title="CorePost 0.0.14 documentation" href="index.html" />
<link rel="next" title="Content types" href="content_types.html" />
<link rel="top" title="CorePost 0.0.16 documentation" href="index.html" />
<link rel="next" title="HTTP codes" href="http_codes.html" />
<link rel="prev" title="Argument parsing" href="argument_parsing.html" />
</head>
<body>
......@@ -37,12 +37,12 @@
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="content_types.html" title="Content types"
<a href="http_codes.html" title="HTTP codes"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="argument_parsing.html" title="Argument parsing"
accesskey="P">previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
......@@ -98,8 +98,8 @@ Validators can be specified using a <em>formencode</em> Schema object, or via cu
<p class="topless"><a href="argument_parsing.html"
title="previous chapter">Argument parsing</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="content_types.html"
title="next chapter">Content types</a></p>
<p class="topless"><a href="http_codes.html"
title="next chapter">HTTP codes</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/arguments.txt"
......@@ -129,12 +129,12 @@ Validators can be specified using a <em>formencode</em> Schema object, or via cu
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="content_types.html" title="Content types"
<a href="http_codes.html" title="HTTP codes"
>next</a> |</li>
<li class="right" >
<a href="argument_parsing.html" title="Argument parsing"
>previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
......
......@@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Asynchronous Operations &mdash; CorePost 0.0.14 documentation</title>
<title>Asynchronous Operations &mdash; CorePost 0.0.16 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
......@@ -16,7 +16,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.0.14',
VERSION: '0.0.16',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
......@@ -25,9 +25,8 @@
<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="top" title="CorePost 0.0.14 documentation" href="index.html" />
<link rel="next" title="Modular REST applications" href="modules.html" />
<link rel="prev" title="HTTP codes" href="http_codes.html" />
<link rel="top" title="CorePost 0.0.16 documentation" href="index.html" />
<link rel="prev" title="Filters" href="filters.html" />
</head>
<body>
<div class="related">
......@@ -37,12 +36,9 @@
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="modules.html" title="Modular REST applications"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="http_codes.html" title="HTTP codes"
<a href="filters.html" title="Filters"
accesskey="P">previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
......@@ -83,11 +79,8 @@
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="http_codes.html"
title="previous chapter">HTTP codes</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="modules.html"
title="next chapter">Modular REST applications</a></p>
<p class="topless"><a href="filters.html"
title="previous chapter">Filters</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/async.txt"
......@@ -117,12 +110,9 @@
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="modules.html" title="Modular REST applications"
>next</a> |</li>
<li class="right" >
<a href="http_codes.html" title="HTTP codes"
<a href="filters.html" title="Filters"
>previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
......
......@@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Content types &mdash; CorePost 0.0.14 documentation</title>
<title>Content types &mdash; CorePost 0.0.16 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
......@@ -16,7 +16,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.0.14',
VERSION: '0.0.16',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
......@@ -25,9 +25,9 @@
<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="top" title="CorePost 0.0.14 documentation" href="index.html" />
<link rel="next" title="Filters" href="filters.html" />
<link rel="prev" title="Argument validation" href="arguments.html" />
<link rel="top" title="CorePost 0.0.16 documentation" href="index.html" />
<link rel="next" title="Modular REST applications" href="modules.html" />
<link rel="prev" title="Returning responses" href="responses.html" />
</head>
<body>
<div class="related">
......@@ -37,12 +37,12 @@
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="filters.html" title="Filters"
<a href="modules.html" title="Modular REST applications"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="arguments.html" title="Argument validation"
<a href="responses.html" title="Returning responses"
accesskey="P">previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
......@@ -116,11 +116,11 @@ Depending whether the caller can accept JSON (default) or YAML, the Python objec
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="arguments.html"
title="previous chapter">Argument validation</a></p>
<p class="topless"><a href="responses.html"
title="previous chapter">Returning responses</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="filters.html"
title="next chapter">Filters</a></p>
<p class="topless"><a href="modules.html"
title="next chapter">Modular REST applications</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/content_types.txt"
......@@ -150,12 +150,12 @@ Depending whether the caller can accept JSON (default) or YAML, the Python objec
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="filters.html" title="Filters"
<a href="modules.html" title="Modular REST applications"
>next</a> |</li>
<li class="right" >
<a href="arguments.html" title="Argument validation"
<a href="responses.html" title="Returning responses"
>previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
......
......@@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Filters &mdash; CorePost 0.0.14 documentation</title>
<title>Filters &mdash; CorePost 0.0.16 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
......@@ -16,7 +16,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.0.14',
VERSION: '0.0.16',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
......@@ -25,9 +25,9 @@
<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="top" title="CorePost 0.0.14 documentation" href="index.html" />
<link rel="next" title="HTTP codes" href="http_codes.html" />
<link rel="prev" title="Content types" href="content_types.html" />
<link rel="top" title="CorePost 0.0.16 documentation" href="index.html" />
<link rel="next" title="Asynchronous Operations" href="async.html" />
<link rel="prev" title="Modular REST applications" href="modules.html" />
</head>
<body>
<div class="related">
......@@ -37,12 +37,12 @@
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="http_codes.html" title="HTTP codes"
<a href="async.html" title="Asynchronous Operations"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="content_types.html" title="Content types"
<a href="modules.html" title="Modular REST applications"
accesskey="P">previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
......@@ -115,11 +115,11 @@
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="content_types.html"
title="previous chapter">Content types</a></p>
<p class="topless"><a href="modules.html"
title="previous chapter">Modular REST applications</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="http_codes.html"
title="next chapter">HTTP codes</a></p>
<p class="topless"><a href="async.html"
title="next chapter">Asynchronous Operations</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/filters.txt"
......@@ -149,12 +149,12 @@
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="http_codes.html" title="HTTP codes"
<a href="async.html" title="Asynchronous Operations"
>next</a> |</li>
<li class="right" >
<a href="content_types.html" title="Content types"
<a href="modules.html" title="Modular REST applications"
>previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
......
......@@ -10,7 +10,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Index &mdash; CorePost 0.0.14 documentation</title>
<title>Index &mdash; CorePost 0.0.16 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
......@@ -18,7 +18,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.0.14',
VERSION: '0.0.16',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
......@@ -27,7 +27,7 @@
<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="top" title="CorePost 0.0.14 documentation" href="index.html" />
<link rel="top" title="CorePost 0.0.16 documentation" href="index.html" />
</head>
<body>
<div class="related">
......@@ -36,7 +36,7 @@
<li class="right" style="margin-right: 10px">
<a href="#" title="General Index"
accesskey="I">index</a></li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
......@@ -84,7 +84,7 @@
<li class="right" style="margin-right: 10px">
<a href="#" title="General Index"
>index</a></li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
......
......@@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>HTTP codes &mdash; CorePost 0.0.14 documentation</title>
<title>HTTP codes &mdash; CorePost 0.0.16 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
......@@ -16,7 +16,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.0.14',
VERSION: '0.0.16',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
......@@ -25,9 +25,9 @@
<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="top" title="CorePost 0.0.14 documentation" href="index.html" />
<link rel="next" title="Asynchronous Operations" href="async.html" />
<link rel="prev" title="Filters" href="filters.html" />
<link rel="top" title="CorePost 0.0.16 documentation" href="index.html" />
<link rel="next" title="Returning responses" href="responses.html" />
<link rel="prev" title="Argument validation" href="arguments.html" />
</head>
<body>
<div class="related">
......@@ -37,12 +37,12 @@
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="async.html" title="Asynchronous Operations"
<a href="responses.html" title="Returning responses"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="filters.html" title="Filters"
<a href="arguments.html" title="Argument validation"
accesskey="P">previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
......@@ -75,11 +75,11 @@
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="filters.html"
title="previous chapter">Filters</a></p>
<p class="topless"><a href="arguments.html"
title="previous chapter">Argument validation</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="async.html"
title="next chapter">Asynchronous Operations</a></p>
<p class="topless"><a href="responses.html"
title="next chapter">Returning responses</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/http_codes.txt"
......@@ -109,12 +109,12 @@
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="async.html" title="Asynchronous Operations"
<a href="responses.html" title="Returning responses"
>next</a> |</li>
<li class="right" >
<a href="filters.html" title="Filters"
<a href="arguments.html" title="Argument validation"
>previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
......
......@@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>CorePost &mdash; CorePost 0.0.14 documentation</title>
<title>CorePost &mdash; CorePost 0.0.16 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
......@@ -16,7 +16,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.0.14',
VERSION: '0.0.16',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
......@@ -25,7 +25,7 @@
<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="top" title="CorePost 0.0.14 documentation" href="#" />
<link rel="top" title="CorePost 0.0.16 documentation" href="#" />
<link rel="next" title="Introduction" href="intro.html" />
</head>
<body>
......@@ -38,7 +38,7 @@
<li class="right" >
<a href="intro.html" title="Introduction"
accesskey="N">next</a> |</li>
<li><a href="#">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="#">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
......@@ -82,18 +82,24 @@
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="arguments.html">Argument validation</a></li>
<li class="toctree-l1"><a class="reference internal" href="http_codes.html">HTTP codes</a></li>
<li class="toctree-l1"><a class="reference internal" href="responses.html">Returning responses</a><ul>
<li class="toctree-l2"><a class="reference internal" href="responses.html#string">String</a></li>
<li class="toctree-l2"><a class="reference internal" href="responses.html#dictionaries-lists-or-classes">Dictionaries, lists or classes</a></li>
<li class="toctree-l2"><a class="reference internal" href="responses.html#response-objects">Response objects</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="content_types.html">Content types</a><ul>
<li class="toctree-l2"><a class="reference internal" href="content_types.html#parsing-of-incoming-content">Parsing of incoming content</a></li>
<li class="toctree-l2"><a class="reference internal" href="content_types.html#converting-python-objects-to-expected-content-type">Converting Python objects to expected content type</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="modules.html">Modular REST applications</a></li>
<li class="toctree-l1"><a class="reference internal" href="filters.html">Filters</a></li>
<li class="toctree-l1"><a class="reference internal" href="http_codes.html">HTTP codes</a></li>
<li class="toctree-l1"><a class="reference internal" href="async.html">Asynchronous Operations</a><ul>
<li class="toctree-l2"><a class="reference internal" href="async.html#defer-inlinecallbacks-support">&#64;defer.inlineCallbacks support</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="modules.html">Modular REST applications</a></li>
</ul>
</div>
</div>
......@@ -152,7 +158,7 @@
<li class="right" >
<a href="intro.html" title="Introduction"
>next</a> |</li>
<li><a href="#">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="#">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
......
......@@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Introduction &mdash; CorePost 0.0.14 documentation</title>
<title>Introduction &mdash; CorePost 0.0.16 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
......@@ -16,7 +16,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.0.14',
VERSION: '0.0.16',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
......@@ -25,7 +25,7 @@
<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="top" title="CorePost 0.0.14 documentation" href="index.html" />
<link rel="top" title="CorePost 0.0.16 documentation" href="index.html" />
<link rel="next" title="URL Routing" href="url_routing.html" />
<link rel="prev" title="CorePost" href="index.html" />
</head>
......@@ -42,7 +42,7 @@
<li class="right" >
<a href="index.html" title="CorePost"
accesskey="P">previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
......@@ -155,7 +155,7 @@ while letting it take care of common required plumbing. That&#8217;s it.</p>
<li class="right" >
<a href="index.html" title="CorePost"
>previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
......
......@@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Modular REST applications &mdash; CorePost 0.0.14 documentation</title>
<title>Modular REST applications &mdash; CorePost 0.0.16 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
......@@ -16,7 +16,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.0.14',
VERSION: '0.0.16',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
......@@ -25,8 +25,9 @@
<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="top" title="CorePost 0.0.14 documentation" href="index.html" />
<link rel="prev" title="Asynchronous Operations" href="async.html" />
<link rel="top" title="CorePost 0.0.16 documentation" href="index.html" />
<link rel="next" title="Filters" href="filters.html" />
<link rel="prev" title="Content types" href="content_types.html" />
</head>
<body>
<div class="related">
......@@ -36,9 +37,12 @@
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="async.html" title="Asynchronous Operations"
<a href="filters.html" title="Filters"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="content_types.html" title="Content types"
accesskey="P">previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
......@@ -180,8 +184,11 @@ and it takes care of routing the request to the appropriate class.</p>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="async.html"
title="previous chapter">Asynchronous Operations</a></p>
<p class="topless"><a href="content_types.html"
title="previous chapter">Content types</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="filters.html"
title="next chapter">Filters</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/modules.txt"
......@@ -211,9 +218,12 @@ and it takes care of routing the request to the appropriate class.</p>
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="async.html" title="Asynchronous Operations"
<a href="filters.html" title="Filters"
>next</a> |</li>
<li class="right" >
<a href="content_types.html" title="Content types"
>previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
......
<!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>Returning responses &mdash; CorePost 0.0.16 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.0.16',
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="top" title="CorePost 0.0.16 documentation" href="index.html" />
<link rel="next" title="Content types" href="content_types.html" />
<link rel="prev" title="HTTP codes" href="http_codes.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="content_types.html" title="Content types"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="http_codes.html" title="HTTP codes"
accesskey="P">previous</a> |</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="returning-responses">
<h1>Returning responses<a class="headerlink" href="#returning-responses" title="Permalink to this headline"></a></h1>
<p>There are a number of ways in which you can return a response from a REST service</p>
<div class="section" id="string">
<h2>String<a class="headerlink" href="#string" title="Permalink to this headline"></a></h2>
<p>You can simply return a plain text String. CorePost will return the appropriate HTTP code for you:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="nd">@route</span><span class="p">(</span><span class="s">&quot;/&quot;</span><span class="p">,</span><span class="n">Http</span><span class="o">.</span><span class="n">GET</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">root</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">request</span><span class="p">,</span><span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">return</span> <span class="s">&quot;Hello&quot;</span>
</pre></div>
</div>
</div>
<div class="section" id="dictionaries-lists-or-classes">
<h2>Dictionaries, lists or classes<a class="headerlink" href="#dictionaries-lists-or-classes" title="Permalink to this headline"></a></h2>
<p>You can return straight dictionaries:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="nd">@route</span><span class="p">(</span><span class="s">&quot;/&quot;</span><span class="p">,</span><span class="n">Http</span><span class="o">.</span><span class="n">GET</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">root</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">request</span><span class="p">,</span><span class="o">**</span><span class="n">kwargs</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;test&quot;</span><span class="p">}</span>
</pre></div>
</div>
<p>or lists:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="nd">@route</span><span class="p">(</span><span class="s">&quot;/&quot;</span><span class="p">,</span><span class="n">Http</span><span class="o">.</span><span class="n">GET</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">root</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">request</span><span class="p">,</span><span class="o">**</span><span class="n">kwargs</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;test&quot;</span><span class="p">},{</span><span class="s">&quot;test&quot;</span><span class="p">:</span><span class="s">&quot;test2&quot;</span><span class="p">}]</span>
</pre></div>
</div>
<p>or classes:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="nd">@route</span><span class="p">(</span><span class="s">&quot;/&quot;</span><span class="p">,</span><span class="n">Http</span><span class="o">.</span><span class="n">GET</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">root</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">request</span><span class="p">,</span><span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">return</span> <span class="n">SomeClass</span><span class="p">()</span>
</pre></div>
</div>
<p>CorePost will serialize each of them to the appropriate content type (JSON,YAML or XML), depending on what the caller can accept.</p>
</div>
<div class="section" id="response-objects">
<h2>Response objects<a class="headerlink" href="#response-objects" title="Permalink to this headline"></a></h2>
<p>This option gives you the most control, as you can explicitly specify the response content, headers and HTTP code.
You need to return an instance of <em>corepost.Response</em> object:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">Response</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Custom response object, can be returned instead of raw string response</span>
<span class="sd"> &quot;&quot;&quot;</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">code</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span><span class="n">entity</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span><span class="n">headers</span><span class="o">=</span><span class="p">{}):</span>
<span class="k">pass</span>
</pre></div>
</div>
<p>Example:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="nd">@route</span><span class="p">(</span><span class="s">&quot;/&quot;</span><span class="p">,</span><span class="n">Http</span><span class="o">.</span><span class="n">POST</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">post</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">request</span><span class="p">,</span><span class="n">customerId</span><span class="p">,</span><span class="n">addressId</span><span class="p">,</span><span class="n">streetNumber</span><span class="p">,</span><span class="n">streetName</span><span class="p">,</span><span class="n">stateCode</span><span class="p">,</span><span class="n">countryCode</span><span class="p">):</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">DB</span><span class="o">.</span><span class="n">getCustomer</span><span class="p">(</span><span class="n">customerId</span><span class="p">)</span>
<span class="n">address</span> <span class="o">=</span> <span class="n">CustomerAddress</span><span class="p">(</span><span class="n">streetNumber</span><span class="p">,</span><span class="n">streetName</span><span class="p">,</span><span class="n">stateCode</span><span class="p">,</span><span class="n">countryCode</span><span class="p">)</span>
<span class="n">c</span><span class="o">.</span><span class="n">addresses</span><span class="p">[</span><span class="n">addressId</span><span class="p">]</span> <span class="o">=</span> <span class="n">address</span>
<span class="k">return</span> <span class="n">Response</span><span class="p">(</span><span class="mi">201</span><span class="p">)</span>
</pre></div>
</div>
</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="#">Returning responses</a><ul>
<li><a class="reference internal" href="#string">String</a></li>
<li><a class="reference internal" href="#dictionaries-lists-or-classes">Dictionaries, lists or classes</a></li>
<li><a class="reference internal" href="#response-objects">Response objects</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="http_codes.html"
title="previous chapter">HTTP codes</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="content_types.html"
title="next chapter">Content types</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/responses.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" />
<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="content_types.html" title="Content types"
>next</a> |</li>
<li class="right" >
<a href="http_codes.html" title="HTTP codes"
>previous</a> |</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2012, Jacek Furmankiewicz.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2.
</div>
</body>
</html>
\ No newline at end of file
......@@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Search &mdash; CorePost 0.0.14 documentation</title>
<title>Search &mdash; CorePost 0.0.16 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
......@@ -16,7 +16,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.0.14',
VERSION: '0.0.16',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
......@@ -26,7 +26,7 @@
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/searchtools.js"></script>
<link rel="top" title="CorePost 0.0.14 documentation" href="index.html" />
<link rel="top" title="CorePost 0.0.16 documentation" href="index.html" />
<script type="text/javascript">
jQuery(function() { Search.loadIndex("searchindex.js"); });
</script>
......@@ -40,7 +40,7 @@
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
......@@ -88,7 +88,7 @@
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
......
Search.setIndex({objects:{},terms:{all:[2,3],code:[0,1,4,5,6,8],partial:5,queri:[2,0,7,9],formencod:7,iresponsefilt:8,follow:8,children:2,rootid:7,depend:5,received_head:[8,4],readabl:6,specif:7,under:6,string:[5,4],veri:6,level:6,list:[7,8],localhost:2,small:3,pleas:7,enterpris:6,fortun:6,abil:6,direct:2,design:6,pass:[2,8,4],val2:9,val1:9,phoneid:3,index:[],what:[0,6],savecustom:3,abl:1,current:[6,4],delet:[3,1],intarg:4,filterrespons:8,method:[2,9,6,1,4],can:[2,3,4,5,7,8],full:3,restservic:4,gener:2,here:3,bodi:5,modular:[0,3],intercept:8,let:[2,6],floatarg:4,address:3,path:[0,3,4],statecod:3,valu:8,convert:[5,0,4],convers:6,extrem:6,chang:8,via:[7,8,4],activ:8,modul:7,countrycod:3,api:6,select:9,regex:7,from:[1,2,3,4,6,7],would:[2,0,6,4],two:[3,8],handler:6,call:5,value2:7,value1:7,recommend:6,type:[2,0,5,8,4],more:6,desir:4,test_yaml:5,phone:3,indic:[],particular:6,known:6,effort:2,customerid:3,content_typ:4,postvalidateschema:7,focu:6,del:3,thin:6,root:[2,9,8,4],def:[2,3,4,5,7,8,9],defer:[0,6,9],tap:4,give:6,accept:5,want:9,multipl:[],write:[6,3,4],how:6,instead:[2,0,6,5],simpl:4,product:[6,4],resourc:[3,8],befor:6,mesh:3,end:3,httpheader:4,tutori:6,seriou:6,element:[2,3],callback:6,allow:[3,8],first:2,order:[3,8],vari:2,dynam:[3,4],entiti:3,yaml:[2,0,6,5],jit:6,main:2,easier:6,them:[2,3,8,4],application_json:4,"return":[1,2,3,4,5,7,8],python:[5,0,6],nation:7,underneath:2,framework:[0,6],introduct:[0,6],name:2,trac:6,easili:4,wraparoundfilt:8,side:6,status:8,hard:6,expect:[2,0,5,4],paymentid:3,extract:[2,0,4],network:6,develop:6,crucial:6,content:[2,0,5,4],restresourc:[3,8,4],deleteal:3,test_content_app_json:4,integr:[5,7],standard:9,pleasant:6,base:[5,1,4],put:[2,5,3,1,4],org:7,care:[6,3],addressid:3,could:2,filter:[0,6,8],router:[2,4],principl:6,interact:6,testschema:7,oper:[0,6,9],note:4,blown:3,grade:6,onc:6,lastnam:3,test_json:5,getallcustom:3,hook:4,miss:1,hood:6,differ:[3,4],addcustomheaderfilt:8,getcustomeraddress:3,customeraddress:3,top:[0,6],system:6,least:6,attach:5,conveni:4,schema:7,customeraddressrestservic:3,specifi:7,pars:[2,0,6,5],streetnumb:3,mostli:6,than:6,john:2,instanc:8,provid:6,structur:3,sai:2,ani:[2,6,1],packag:7,have:[2,3],"__main__":[3,4],need:8,inlinecallback:[0,9],test_return_content_by_accept:5,self:[2,3,4,5,7,8,9],especi:6,thorough:6,stringarg:4,mix:2,without:2,take:[6,3],which:[6,3],noth:6,singl:[2,3],simplifi:6,importantli:6,deletecustom:3,regular:3,why:[0,6],url:[5,0,3,1,4],request:[0,2,3,4,5,6,7,8,9],doe:[2,0,6],test_content_xml:4,runtim:6,wildcard:4,numericid:4,somewhat:6,show:4,text:[2,5],xml:[2,0,6,5],onli:2,just:[2,3,4,5,6,8,9],solut:6,plumb:6,should:6,busi:[6,3],meant:6,get:[1,2,3,4,6,8,9],pypi:6,requir:[2,6],run_filter_app:8,change404to503filt:8,yield:9,"default":[5,1],common:[6,7],deleteallcustom:3,where:3,valid:[2,0,3,1,7],respond:2,dump:5,see:[2,7],mandatori:1,respons:[2,5,6,3,8],fail:1,extend:3,hopefulli:6,databas:6,behind:6,"import":[3,7,4],paramet:[2,3,8],approach:6,attribut:2,parent:3,addit:2,both:8,last:2,howev:6,test_content_catch_al:4,etc:[3,4],text_xml:4,logic:6,pdf:6,com:[6,4],simpli:6,header:8,guid:6,coupl:6,json:[2,0,6,5],much:6,basic:[2,6,4],search:[],argument:[2,0,1,7,4],notfoundexcept:3,dave:6,run_rest_app:3,child:[2,3],those:2,"case":[2,3],look:2,tostr:5,servic:[6,3,8],"while":6,abov:[2,3],error:1,fun:6,exist:[3,4],layer:6,twistedmatrix:[6,4],tabl:[],henc:[2,6],toolkit:6,kwarg:[2,4,5,7,8,9],myapp:7,postvalidatecustom:7,incom:[5,0,8,4],twistd:4,decor:[0,4],allow_extra_field:7,perform:6,make:6,same:[2,4],handl:[2,6],html:[7,4],zope:8,document:[2,0,6,7,4],breakdown:[],http:[0,1,2,3,4,5,6,7,8,9],driven:[3,1],extern:6,typic:3,appropri:[3,1],eleg:6,well:[2,6],coreport:4,exampl:[2,3,7,4],thi:[2,3,4,5,6,9],rout:[0,3,4,5,6,7,8,9],latest:7,test1:5,test2:5,firstnam:3,when:4,rest:[2,0,6,3],filterapp:8,test_content_yaml:4,yet:6,languag:6,web:[0,6,3,7,4],application_xml:4,except:6,getal:3,blog:6,add:[0,6,8],book:6,input:[6,8],app:[3,8,4],match:1,build:6,real:4,applic:[0,2,3,4,5,6],around:8,format:[2,6],read:6,irequestfilt:8,howto:[6,4],piec:4,realiz:6,like:[2,6,3],success:1,filterrequest:8,test_get_resourc:4,either:[6,8],popular:7,output:[2,8],page:[],childid:7,www:7,some:6,back:2,sampl:[3,4],server:[6,1],librari:6,kei:[],getcustom:3,micro:[0,6],peticola:6,outgo:8,unit:4,test_xml:5,complic:6,getnam:2,core:[6,4],object:[0,3,4,5,6,7],run:[3,8,4],power:6,payment:3,"enum":[7,4],usag:6,alreadyexistsexcept:3,async:[9,6],"__name__":[3,4],post:[1,2,3,4,5,7],actual:1,constructor:8,other:6,own:6,effici:6,"float":4,encod:[2,0],automat:[2,5,6,4],wrap:[3,8],your:4,invoiceid:3,val:5,support:[0,2,4,5,8,9],custom:[6,3,7,8],avail:7,reli:6,interfac:8,low:6,"function":[9,1,4],returnvalu:9,form:[2,0,7],streetnam:3,inlin:6,"true":7,whether:5,page_id:6,caller:5,asynchron:[0,6,9],below:2,similar:6,featur:[0,6],creat:[6,3,1],"int":[7,4],customerrestservic:3,twist:[0,6,3,9,4],implement:[3,7,8],curl:2,krondo:6,excel:6,elementtre:5,field:7,corepost:[0,1,2,3,4,5,6,7,8],test:4,you:[2,3,4,6,8,9],node:[2,0,6],matur:6,mediatyp:4,"class":[6,3,7,8,4],sql:6,text_yaml:4,understand:6,invoic:3},objtypes:{},titles:["CorePost","HTTP codes","Argument parsing","Modular REST applications","URL Routing","Content types","Introduction","Argument validation","Filters","Asynchronous Operations"],objnames:{},filenames:["index","http_codes","argument_parsing","modules","url_routing","content_types","intro","arguments","filters","async"]})
\ No newline at end of file
Search.setIndex({objects:{},terms:{all:[2,3],code:[0,1,4,5,6,8,10],partial:5,queri:[2,0,7,9],formencod:7,iresponsefilt:8,follow:8,children:2,rootid:7,depend:[5,10],received_head:[8,4],readabl:6,specif:7,under:6,string:[5,0,10,4],veri:6,level:6,list:[0,7,8,10],localhost:2,plain:10,small:3,straight:10,pleas:7,enterpris:6,fortun:6,abil:6,direct:2,design:6,pass:[2,10,8,4],val2:9,val1:9,phoneid:3,index:[],what:[0,6,10],savecustom:3,abl:1,current:[6,4],delet:[3,1],intarg:4,filterrespons:8,method:[2,9,6,1,4],can:[10,2,3,4,5,7,8],full:3,restservic:4,gener:2,here:3,bodi:5,modular:[0,3],intercept:8,let:[2,6],floatarg:4,address:[3,10],path:[0,3,4],statecod:[3,10],valu:8,convert:[5,0,4],convers:6,extrem:6,chang:8,via:[7,8,4],activ:8,modul:7,countrycod:[3,10],api:6,select:9,regex:7,from:[1,2,3,4,6,7,10],would:[2,0,6,4],two:[3,8],handler:6,call:5,value2:7,value1:7,recommend:6,type:[0,10,2,4,5,8],more:6,desir:4,test_yaml:5,phone:3,indic:[],particular:6,known:6,effort:2,customerid:[3,10],content_typ:4,none:10,postvalidateschema:7,focu:6,del:3,thin:6,root:[2,9,10,8,4],def:[10,2,3,4,5,7,8,9],control:10,defer:[0,6,9],tap:4,give:[6,10],accept:[5,10],want:9,serial:10,multipl:[],write:[6,3,4],how:6,instead:[2,0,6,5,10],simpl:4,product:[6,4],resourc:[3,8],befor:6,mesh:3,end:3,httpheader:4,tutori:6,seriou:6,element:[2,3],callback:6,allow:[3,8],first:2,order:[3,8],vari:2,dynam:[3,4],entiti:[3,10],yaml:[2,0,6,5,10],jit:6,main:2,easier:6,them:[2,3,10,8,4],application_json:4,"return":[0,1,2,3,4,5,7,8,10],python:[5,0,6],nation:7,underneath:2,framework:[0,6],introduct:[0,6],name:2,trac:6,easili:4,wraparoundfilt:8,each:10,side:6,status:8,hard:6,expect:[2,0,5,4],paymentid:3,extract:[2,0,4],network:6,develop:6,crucial:6,content:[2,0,10,5,4],restresourc:[3,8,4],deleteal:3,test_content_app_json:4,integr:[5,7],standard:9,pleasant:6,base:[5,1,4],dictionari:[0,10],put:[2,5,3,1,4],org:7,care:[6,3],wai:10,addressid:[3,10],could:2,filter:[0,6,8],router:[2,4],principl:6,interact:6,testschema:7,oper:[0,6,9],note:4,blown:3,grade:6,onc:6,lastnam:3,test_json:5,number:10,getallcustom:3,hook:4,miss:1,hood:6,differ:[3,4],addcustomheaderfilt:8,getcustomeraddress:3,customeraddress:[3,10],top:[0,6],system:6,least:6,attach:5,conveni:4,schema:7,option:10,customeraddressrestservic:3,specifi:[7,10],pars:[2,0,6,5],streetnumb:[3,10],mostli:6,than:6,john:2,instanc:[10,8],provid:6,structur:3,sai:2,ani:[2,6,1],raw:10,have:[2,3],"__main__":[3,4],need:[10,8],inlinecallback:[0,9],test_return_content_by_accept:5,self:[10,2,3,4,5,7,8,9],especi:6,thorough:6,stringarg:4,mix:2,without:2,take:[6,3],which:[6,3,10],noth:6,singl:[2,3],simplifi:6,importantli:6,deletecustom:3,most:10,regular:3,why:[0,6],url:[5,0,3,1,4],request:[0,10,2,3,4,5,6,7,8,9],doe:[2,0,6],test_content_xml:4,runtim:6,wildcard:4,numericid:4,somewhat:6,show:4,text:[2,5,10],xml:[2,0,6,5,10],onli:2,explicitli:10,just:[2,3,4,5,6,8,9],solut:6,plumb:6,should:6,busi:[6,3],meant:6,get:[1,2,3,4,6,8,9,10],pypi:6,requir:[2,6],run_filter_app:8,change404to503filt:8,yield:9,"default":[5,1],common:[6,7],deleteallcustom:3,where:3,valid:[2,0,3,1,7],respond:2,dump:5,see:[2,7],mandatori:1,respons:[0,10,2,3,5,6,8],fail:1,extend:3,hopefulli:6,databas:6,behind:6,"import":[3,7,4],paramet:[2,3,8],approach:6,attribut:2,parent:3,addit:2,both:8,last:2,howev:6,test_content_catch_al:4,etc:[3,4],text_xml:4,logic:6,pdf:6,com:[6,4],simpli:[6,10],header:[10,8],guid:6,coupl:6,json:[2,0,6,5,10],much:6,basic:[2,6,4],search:[],argument:[2,0,1,7,4],notfoundexcept:3,dave:6,run_rest_app:3,child:[2,3],those:2,"case":[2,3],look:2,packag:7,tostr:5,servic:[6,3,10,8],"while":6,abov:[2,3],error:1,fun:6,exist:[3,4],layer:6,twistedmatrix:[6,4],tabl:[],henc:[2,6],toolkit:6,kwarg:[10,2,4,5,7,8,9],myapp:7,postvalidatecustom:7,incom:[5,0,8,4],twistd:4,"__init__":10,decor:[0,4],allow_extra_field:7,perform:6,make:6,same:[2,4],handl:[2,6],html:[7,4],zope:8,document:[2,0,6,7,4],breakdown:[],http:[0,1,2,3,4,5,6,7,8,9,10],driven:[3,1],extern:6,typic:3,appropri:[3,1,10],eleg:6,well:[2,6],coreport:4,exampl:[2,10,3,7,4],thi:[10,2,3,4,5,6,9],rout:[0,10,3,4,5,6,7,8,9],latest:7,test1:5,test2:[5,10],firstnam:3,when:4,rest:[2,0,6,3,10],filterapp:8,test_content_yaml:4,yet:6,languag:6,web:[0,6,3,7,4],application_xml:4,except:6,getal:3,blog:6,add:[0,6,8],book:6,input:[6,8],app:[3,8,4],match:1,build:6,real:4,applic:[0,2,3,4,5,6],around:8,format:[2,6],read:6,irequestfilt:8,howto:[6,4],piec:4,realiz:6,like:[2,6,3],success:1,filterrequest:8,test_get_resourc:4,either:[6,8],popular:7,output:[2,8],page:[],childid:7,www:7,some:6,back:2,sampl:[3,4],server:[6,1],librari:6,kei:[],getcustom:[3,10],micro:[0,6],peticola:6,outgo:8,unit:4,test_xml:5,complic:6,getnam:2,core:[6,4],object:[0,10,3,4,5,6,7],run:[3,8,4],power:6,someclass:10,payment:3,"enum":[7,4],usag:6,alreadyexistsexcept:3,async:[9,6],"__name__":[3,4],post:[1,2,3,4,5,7,10],actual:1,constructor:8,other:6,own:6,effici:6,"float":4,encod:[2,0],automat:[2,5,6,4],wrap:[3,8],your:4,invoiceid:3,val:5,support:[0,2,4,5,8,9],custom:[6,3,7,8,10],avail:7,reli:6,interfac:8,low:6,"function":[9,1,4],returnvalu:9,form:[2,0,7],streetnam:[3,10],inlin:6,"true":7,whether:5,page_id:6,caller:[5,10],asynchron:[0,6,9],below:2,similar:6,featur:[0,6],creat:[6,3,1],"int":[7,4],customerrestservic:3,twist:[0,6,3,9,4],implement:[3,7,8],curl:2,krondo:6,excel:6,elementtre:5,field:7,corepost:[0,1,2,3,4,5,6,7,8,10],test:[10,4],you:[10,2,3,4,6,8,9],node:[2,0,6],matur:6,mediatyp:4,"class":[0,10,3,4,6,7,8],sql:6,text_yaml:4,understand:6,invoic:3,hello:10},objtypes:{},titles:["CorePost","HTTP codes","Argument parsing","Modular REST applications","URL Routing","Content types","Introduction","Argument validation","Filters","Asynchronous Operations","Returning responses"],objnames:{},filenames:["index","http_codes","argument_parsing","modules","url_routing","content_types","intro","arguments","filters","async","responses"]})
\ No newline at end of file
......@@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>URL Routing &mdash; CorePost 0.0.14 documentation</title>
<title>URL Routing &mdash; CorePost 0.0.16 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
......@@ -16,7 +16,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.0.14',
VERSION: '0.0.16',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
......@@ -25,7 +25,7 @@
<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="top" title="CorePost 0.0.14 documentation" href="index.html" />
<link rel="top" title="CorePost 0.0.16 documentation" href="index.html" />
<link rel="next" title="Argument parsing" href="argument_parsing.html" />
<link rel="prev" title="Introduction" href="intro.html" />
</head>
......@@ -42,7 +42,7 @@
<li class="right" >
<a href="intro.html" title="Introduction"
accesskey="P">previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
......@@ -189,7 +189,7 @@ In a real production application you would use existing Twisted <em>twistd</em>
<li class="right" >
<a href="intro.html" title="Introduction"
>previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
<li><a href="index.html">CorePost 0.0.16 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
......
......@@ -61,24 +61,33 @@
\@writefile{toc}{\contentsline {section}{\numberline {2.3}Argument validation}{6}{section.2.3}}
\newlabel{arguments:argument-validation}{{2.3}{6}{Argument validation\relax }{section.2.3}{}}
\newlabel{arguments::doc}{{2.3}{6}{Argument validation\relax }{section.2.3}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.4}Content types}{6}{section.2.4}}
\newlabel{content_types::doc}{{2.4}{6}{Content types\relax }{section.2.4}{}}
\newlabel{content_types:content-types}{{2.4}{6}{Content types\relax }{section.2.4}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.4.1}Parsing of incoming content}{6}{subsection.2.4.1}}
\newlabel{content_types:parsing-of-incoming-content}{{2.4.1}{6}{Parsing of incoming content\relax }{subsection.2.4.1}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.4.2}Converting Python objects to expected content type}{7}{subsection.2.4.2}}
\newlabel{content_types:converting-python-objects-to-expected-content-type}{{2.4.2}{7}{Converting Python objects to expected content type\relax }{subsection.2.4.2}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.5}Filters}{7}{section.2.5}}
\newlabel{filters::doc}{{2.5}{7}{Filters\relax }{section.2.5}{}}
\newlabel{filters:filters}{{2.5}{7}{Filters\relax }{section.2.5}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.6}HTTP codes}{8}{section.2.6}}
\newlabel{http_codes::doc}{{2.6}{8}{HTTP codes\relax }{section.2.6}{}}
\newlabel{http_codes:http-codes}{{2.6}{8}{HTTP codes\relax }{section.2.6}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.7}Asynchronous Operations}{8}{section.2.7}}
\newlabel{async:asynchronous-operations}{{2.7}{8}{Asynchronous Operations\relax }{section.2.7}{}}
\newlabel{async::doc}{{2.7}{8}{Asynchronous Operations\relax }{section.2.7}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.7.1}@defer.inlineCallbacks support}{8}{subsection.2.7.1}}
\newlabel{async:defer-inlinecallbacks-support}{{2.7.1}{8}{@defer.inlineCallbacks support\relax }{subsection.2.7.1}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.8}Modular REST applications}{9}{section.2.8}}
\newlabel{modules::doc}{{2.8}{9}{Modular REST applications\relax }{section.2.8}{}}
\newlabel{modules:modular-rest-applications}{{2.8}{9}{Modular REST applications\relax }{section.2.8}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.4}HTTP codes}{6}{section.2.4}}
\newlabel{http_codes::doc}{{2.4}{6}{HTTP codes\relax }{section.2.4}{}}
\newlabel{http_codes:http-codes}{{2.4}{6}{HTTP codes\relax }{section.2.4}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.5}Returning responses}{7}{section.2.5}}
\newlabel{responses::doc}{{2.5}{7}{Returning responses\relax }{section.2.5}{}}
\newlabel{responses:returning-responses}{{2.5}{7}{Returning responses\relax }{section.2.5}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.5.1}String}{7}{subsection.2.5.1}}
\newlabel{responses:string}{{2.5.1}{7}{String\relax }{subsection.2.5.1}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.5.2}Dictionaries, lists or classes}{7}{subsection.2.5.2}}
\newlabel{responses:dictionaries-lists-or-classes}{{2.5.2}{7}{Dictionaries, lists or classes\relax }{subsection.2.5.2}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.5.3}Response objects}{7}{subsection.2.5.3}}
\newlabel{responses:response-objects}{{2.5.3}{7}{Response objects\relax }{subsection.2.5.3}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.6}Content types}{8}{section.2.6}}
\newlabel{content_types::doc}{{2.6}{8}{Content types\relax }{section.2.6}{}}
\newlabel{content_types:content-types}{{2.6}{8}{Content types\relax }{section.2.6}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.6.1}Parsing of incoming content}{8}{subsection.2.6.1}}
\newlabel{content_types:parsing-of-incoming-content}{{2.6.1}{8}{Parsing of incoming content\relax }{subsection.2.6.1}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.6.2}Converting Python objects to expected content type}{8}{subsection.2.6.2}}
\newlabel{content_types:converting-python-objects-to-expected-content-type}{{2.6.2}{8}{Converting Python objects to expected content type\relax }{subsection.2.6.2}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.7}Modular REST applications}{8}{section.2.7}}
\newlabel{modules::doc}{{2.7}{8}{Modular REST applications\relax }{section.2.7}{}}
\newlabel{modules:modular-rest-applications}{{2.7}{8}{Modular REST applications\relax }{section.2.7}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.8}Filters}{11}{section.2.8}}
\newlabel{filters::doc}{{2.8}{11}{Filters\relax }{section.2.8}{}}
\newlabel{filters:filters}{{2.8}{11}{Filters\relax }{section.2.8}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.9}Asynchronous Operations}{12}{section.2.9}}
\newlabel{async:asynchronous-operations}{{2.9}{12}{Asynchronous Operations\relax }{section.2.9}{}}
\newlabel{async::doc}{{2.9}{12}{Asynchronous Operations\relax }{section.2.9}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.9.1}@defer.inlineCallbacks support}{12}{subsection.2.9.1}}
\newlabel{async:defer-inlinecallbacks-support}{{2.9.1}{12}{@defer.inlineCallbacks support\relax }{subsection.2.9.1}{}}
This is pdfTeX, Version 3.1415926-1.40.10 (TeX Live 2009/Debian) (format=pdflatex 2012.3.27) 17 APR 2012 16:18
This is pdfTeX, Version 3.1415926-1.40.10 (TeX Live 2009/Debian) (format=pdflatex 2012.3.27) 20 APR 2012 15:28
entering extended mode
%&-line parsing enabled.
**CorePost.tex
......@@ -904,33 +904,33 @@ LaTeX Font Info: Font shape `T1/pcr/m/it' in size <9> not available
] [4] [5] [6] [7]
[8] [9]
Underfull \vbox (badness 10000) detected at line 750
Underfull \vbox (badness 10000) detected at line 740
[]
Underfull \vbox (badness 10000) detected at line 750
Underfull \vbox (badness 10000) detected at line 740
[]
[10] (./CorePost.ind) [11] (./CorePost.aux) )
[10] [11] (./CorePost.ind) [12] (./CorePost.aux) )
Here is how much of TeX's memory you used:
7981 strings out of 493848
108170 string characters out of 1152823
197503 words of memory out of 3000000
11019 multiletter control sequences out of 15000+50000
7992 strings out of 493848
108383 string characters out of 1152823
197759 words of memory out of 3000000
11025 multiletter control sequences out of 15000+50000
55793 words of font info for 63 fonts, out of 3000000 for 9000
715 hyphenation exceptions out of 8191
45i,12n,45p,426b,381s stack positions out of 5000i,500n,10000p,200000b,50000s
{/usr/share/texmf-texlive/fonts/en
c/dvips/base/8r.enc}</usr/share/texmf-texlive/fonts/type1/urw/courier/ucrb8a.pf
b></usr/share/texmf-texlive/fonts/type1/urw/courier/ucrr8a.pfb></usr/share/texm
f-texlive/fonts/type1/urw/courier/ucrro8a.pfb></usr/share/texmf-texlive/fonts/t
ype1/urw/helvetic/uhvb8a.pfb></usr/share/texmf-texlive/fonts/type1/urw/helvetic
/uhvbo8a.pfb></usr/share/texmf-texlive/fonts/type1/urw/times/utmb8a.pfb></usr/s
hare/texmf-texlive/fonts/type1/urw/times/utmr8a.pfb></usr/share/texmf-texlive/f
onts/type1/urw/times/utmri8a.pfb>
Output written on CorePost.pdf (15 pages, 149328 bytes).
{/usr/share/texmf-texlive/fon
ts/enc/dvips/base/8r.enc}</usr/share/texmf-texlive/fonts/type1/urw/courier/ucrb
8a.pfb></usr/share/texmf-texlive/fonts/type1/urw/courier/ucrr8a.pfb></usr/share
/texmf-texlive/fonts/type1/urw/courier/ucrro8a.pfb></usr/share/texmf-texlive/fo
nts/type1/urw/helvetic/uhvb8a.pfb></usr/share/texmf-texlive/fonts/type1/urw/hel
vetic/uhvbo8a.pfb></usr/share/texmf-texlive/fonts/type1/urw/times/utmb8a.pfb></
usr/share/texmf-texlive/fonts/type1/urw/times/utmr8a.pfb></usr/share/texmf-texl
ive/fonts/type1/urw/times/utmri8a.pfb>
Output written on CorePost.pdf (16 pages, 153055 bytes).
PDF statistics:
192 PDF objects out of 1000 (max. 8388607)
42 named destinations out of 1000 (max. 500000)
89 words of extra memory for PDF output out of 10000 (max. 10000000)
205 PDF objects out of 1000 (max. 8388607)
47 named destinations out of 1000 (max. 500000)
97 words of extra memory for PDF output out of 10000 (max. 10000000)
......@@ -4,8 +4,9 @@
\BOOKMARK [1][-]{section.2.1}{URL Routing}{chapter.2}
\BOOKMARK [1][-]{section.2.2}{Argument parsing}{chapter.2}
\BOOKMARK [1][-]{section.2.3}{Argument validation}{chapter.2}
\BOOKMARK [1][-]{section.2.4}{Content types}{chapter.2}
\BOOKMARK [1][-]{section.2.5}{Filters}{chapter.2}
\BOOKMARK [1][-]{section.2.6}{HTTP codes}{chapter.2}
\BOOKMARK [1][-]{section.2.7}{Asynchronous Operations}{chapter.2}
\BOOKMARK [1][-]{section.2.8}{Modular REST applications}{chapter.2}
\BOOKMARK [1][-]{section.2.4}{HTTP codes}{chapter.2}
\BOOKMARK [1][-]{section.2.5}{Returning responses}{chapter.2}
\BOOKMARK [1][-]{section.2.6}{Content types}{chapter.2}
\BOOKMARK [1][-]{section.2.7}{Modular REST applications}{chapter.2}
\BOOKMARK [1][-]{section.2.8}{Filters}{chapter.2}
\BOOKMARK [1][-]{section.2.9}{Asynchronous Operations}{chapter.2}
......@@ -13,8 +13,8 @@
\title{CorePost Documentation}
\date{April 17, 2012}
\release{0.0.14}
\date{April 20, 2012}
\release{0.0.16}
\author{Jacek Furmankiewicz}
\newcommand{\sphinxlogo}{}
\renewcommand{\releasename}{Release}
......@@ -438,6 +438,108 @@ National : \href{http://www.formencode.org/en/latest/modules/national.html\#modu
\end{itemize}
\section{HTTP codes}
\label{http_codes::doc}\label{http_codes:http-codes}
By default, CorePost returns the appropriate HTTP code based on the HTTP method:
Success:
\begin{itemize}
\item {}
200 (OK) - GET, DELETE, PUT
\item {}
201 (Created) - POST
\end{itemize}
Errors:
\begin{itemize}
\item {}
404 - not able to match any URL.
\item {}
400 - missing mandatory argument (driven from the arguments on the actual functions)
\item {}
400 - argument failed validation
\item {}
500 - server error
\end{itemize}
\section{Returning responses}
\label{responses::doc}\label{responses:returning-responses}
There are a number of ways in which you can return a response from a REST service
\subsection{String}
\label{responses:string}
You can simply return a plain text String. CorePost will return the appropriate HTTP code for you:
\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n+nd}{@route}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/}\PYG{l+s}{"}\PYG{p}{,}\PYG{n}{Http}\PYG{o}{.}\PYG{n}{GET}\PYG{p}{)}
\PYG{k}{def} \PYG{n+nf}{root}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{,}\PYG{o}{*}\PYG{o}{*}\PYG{n}{kwargs}\PYG{p}{)}\PYG{p}{:}
\PYG{k}{return} \PYG{l+s}{"}\PYG{l+s}{Hello}\PYG{l+s}{"}
\end{Verbatim}
\subsection{Dictionaries, lists or classes}
\label{responses:dictionaries-lists-or-classes}
You can return straight dictionaries:
\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n+nd}{@route}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/}\PYG{l+s}{"}\PYG{p}{,}\PYG{n}{Http}\PYG{o}{.}\PYG{n}{GET}\PYG{p}{)}
\PYG{k}{def} \PYG{n+nf}{root}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{,}\PYG{o}{*}\PYG{o}{*}\PYG{n}{kwargs}\PYG{p}{)}\PYG{p}{:}
\PYG{k}{return} \PYG{p}{\PYGZob{}}\PYG{l+s}{"}\PYG{l+s}{test}\PYG{l+s}{"}\PYG{p}{:}\PYG{l+s}{"}\PYG{l+s}{test}\PYG{l+s}{"}\PYG{p}{\PYGZcb{}}
\end{Verbatim}
or lists:
\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n+nd}{@route}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/}\PYG{l+s}{"}\PYG{p}{,}\PYG{n}{Http}\PYG{o}{.}\PYG{n}{GET}\PYG{p}{)}
\PYG{k}{def} \PYG{n+nf}{root}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{,}\PYG{o}{*}\PYG{o}{*}\PYG{n}{kwargs}\PYG{p}{)}\PYG{p}{:}
\PYG{k}{return} \PYG{p}{[}\PYG{p}{\PYGZob{}}\PYG{l+s}{"}\PYG{l+s}{test}\PYG{l+s}{"}\PYG{p}{:}\PYG{l+s}{"}\PYG{l+s}{test}\PYG{l+s}{"}\PYG{p}{\PYGZcb{}}\PYG{p}{,}\PYG{p}{\PYGZob{}}\PYG{l+s}{"}\PYG{l+s}{test}\PYG{l+s}{"}\PYG{p}{:}\PYG{l+s}{"}\PYG{l+s}{test2}\PYG{l+s}{"}\PYG{p}{\PYGZcb{}}\PYG{p}{]}
\end{Verbatim}
or classes:
\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n+nd}{@route}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/}\PYG{l+s}{"}\PYG{p}{,}\PYG{n}{Http}\PYG{o}{.}\PYG{n}{GET}\PYG{p}{)}
\PYG{k}{def} \PYG{n+nf}{root}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{,}\PYG{o}{*}\PYG{o}{*}\PYG{n}{kwargs}\PYG{p}{)}\PYG{p}{:}
\PYG{k}{return} \PYG{n}{SomeClass}\PYG{p}{(}\PYG{p}{)}
\end{Verbatim}
CorePost will serialize each of them to the appropriate content type (JSON,YAML or XML), depending on what the caller can accept.
\subsection{Response objects}
\label{responses:response-objects}
This option gives you the most control, as you can explicitly specify the response content, headers and HTTP code.
You need to return an instance of \emph{corepost.Response} object:
\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{class} \PYG{n+nc}{Response}\PYG{p}{:}
\PYG{l+s+sd}{"""}
\PYG{l+s+sd}{ Custom response object, can be returned instead of raw string response}
\PYG{l+s+sd}{ """}
\PYG{k}{def} \PYG{n+nf}{\PYGZus{}\PYGZus{}init\PYGZus{}\PYGZus{}}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{code}\PYG{o}{=}\PYG{l+m+mi}{200}\PYG{p}{,}\PYG{n}{entity}\PYG{o}{=}\PYG{n+nb+bp}{None}\PYG{p}{,}\PYG{n}{headers}\PYG{o}{=}\PYG{p}{\PYGZob{}}\PYG{p}{\PYGZcb{}}\PYG{p}{)}\PYG{p}{:}
\PYG{k}{pass}
\end{Verbatim}
Example:
\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n+nd}{@route}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/}\PYG{l+s}{"}\PYG{p}{,}\PYG{n}{Http}\PYG{o}{.}\PYG{n}{POST}\PYG{p}{)}
\PYG{k}{def} \PYG{n+nf}{post}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{,}\PYG{n}{customerId}\PYG{p}{,}\PYG{n}{addressId}\PYG{p}{,}\PYG{n}{streetNumber}\PYG{p}{,}\PYG{n}{streetName}\PYG{p}{,}\PYG{n}{stateCode}\PYG{p}{,}\PYG{n}{countryCode}\PYG{p}{)}\PYG{p}{:}
\PYG{n}{c} \PYG{o}{=} \PYG{n}{DB}\PYG{o}{.}\PYG{n}{getCustomer}\PYG{p}{(}\PYG{n}{customerId}\PYG{p}{)}
\PYG{n}{address} \PYG{o}{=} \PYG{n}{CustomerAddress}\PYG{p}{(}\PYG{n}{streetNumber}\PYG{p}{,}\PYG{n}{streetName}\PYG{p}{,}\PYG{n}{stateCode}\PYG{p}{,}\PYG{n}{countryCode}\PYG{p}{)}
\PYG{n}{c}\PYG{o}{.}\PYG{n}{addresses}\PYG{p}{[}\PYG{n}{addressId}\PYG{p}{]} \PYG{o}{=} \PYG{n}{address}
\PYG{k}{return} \PYG{n}{Response}\PYG{p}{(}\PYG{l+m+mi}{201}\PYG{p}{)}
\end{Verbatim}
\section{Content types}
\label{content_types::doc}\label{content_types:content-types}
CorePost integrates support for JSON, YAML and XML (partially) based on request content types.
......@@ -502,118 +604,6 @@ Calling it with ``Accept: text/yaml'' will return:
\end{Verbatim}
\section{Filters}
\label{filters::doc}\label{filters:filters}
There is support for CorePost resource filters via the two following \emph{corepost.filter} interfaces:
\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{class} \PYG{n+nc}{IRequestFilter}\PYG{p}{(}\PYG{n}{Interface}\PYG{p}{)}\PYG{p}{:}
\PYG{l+s+sd}{"""Request filter interface"""}
\PYG{k}{def} \PYG{n+nf}{filterRequest}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{)}\PYG{p}{:}
\PYG{l+s+sd}{"""Allows to intercept and change an incoming request"""}
\PYG{k}{pass}
\PYG{k}{class} \PYG{n+nc}{IResponseFilter}\PYG{p}{(}\PYG{n}{Interface}\PYG{p}{)}\PYG{p}{:}
\PYG{l+s+sd}{"""Response filter interface"""}
\PYG{k}{def} \PYG{n+nf}{filterResponse}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{,}\PYG{n}{response}\PYG{p}{)}\PYG{p}{:}
\PYG{l+s+sd}{"""Allows to intercept and change an outgoing response"""}
\PYG{k}{pass}
\end{Verbatim}
A filter class can implement either of them or both (for a wrap around filter), e.g.:
\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{class} \PYG{n+nc}{AddCustomHeaderFilter}\PYG{p}{(}\PYG{p}{)}\PYG{p}{:}
\PYG{l+s+sd}{"""Implements a request filter that adds a custom header to the incoming request"""}
\PYG{n}{zope}\PYG{o}{.}\PYG{n}{interface}\PYG{o}{.}\PYG{n}{implements}\PYG{p}{(}\PYG{n}{IRequestFilter}\PYG{p}{)}
\PYG{k}{def} \PYG{n+nf}{filterRequest}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{)}\PYG{p}{:}
\PYG{n}{request}\PYG{o}{.}\PYG{n}{received\PYGZus{}headers}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{Custom-Header}\PYG{l+s}{"}\PYG{p}{]} \PYG{o}{=} \PYG{l+s}{"}\PYG{l+s}{Custom Header Value}\PYG{l+s}{"}
\PYG{k}{class} \PYG{n+nc}{Change404to503Filter}\PYG{p}{(}\PYG{p}{)}\PYG{p}{:}
\PYG{l+s+sd}{"""Implements just a response filter that changes 404 to 503 statuses"""}
\PYG{n}{zope}\PYG{o}{.}\PYG{n}{interface}\PYG{o}{.}\PYG{n}{implements}\PYG{p}{(}\PYG{n}{IResponseFilter}\PYG{p}{)}
\PYG{k}{def} \PYG{n+nf}{filterResponse}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{,}\PYG{n}{response}\PYG{p}{)}\PYG{p}{:}
\PYG{k}{if} \PYG{n}{response}\PYG{o}{.}\PYG{n}{code} \PYG{o}{==} \PYG{l+m+mi}{404}\PYG{p}{:}
\PYG{n}{response}\PYG{o}{.}\PYG{n}{code} \PYG{o}{=} \PYG{l+m+mi}{503}
\PYG{k}{class} \PYG{n+nc}{WrapAroundFilter}\PYG{p}{(}\PYG{p}{)}\PYG{p}{:}
\PYG{l+s+sd}{"""Implements both types of filters in one class"""}
\PYG{n}{zope}\PYG{o}{.}\PYG{n}{interface}\PYG{o}{.}\PYG{n}{implements}\PYG{p}{(}\PYG{n}{IRequestFilter}\PYG{p}{,}\PYG{n}{IResponseFilter}\PYG{p}{)}
\PYG{k}{def} \PYG{n+nf}{filterRequest}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{)}\PYG{p}{:}
\PYG{n}{request}\PYG{o}{.}\PYG{n}{received\PYGZus{}headers}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{X-Wrap-Input}\PYG{l+s}{"}\PYG{p}{]} \PYG{o}{=} \PYG{l+s}{"}\PYG{l+s}{Input}\PYG{l+s}{"}
\PYG{k}{def} \PYG{n+nf}{filterResponse}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{,}\PYG{n}{response}\PYG{p}{)}\PYG{p}{:}
\PYG{n}{response}\PYG{o}{.}\PYG{n}{headers}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{X-Wrap-Output}\PYG{l+s}{"}\PYG{p}{]} \PYG{o}{=} \PYG{l+s}{"}\PYG{l+s}{Output}\PYG{l+s}{"}
\end{Verbatim}
In order to activate the filters on a RESTResource instance, you need to pass a list of them in the constructor as the \emph{filters} parameter, e.g.:
\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{class} \PYG{n+nc}{FilterApp}\PYG{p}{:}
\PYG{n+nd}{@route}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/}\PYG{l+s}{"}\PYG{p}{,}\PYG{n}{Http}\PYG{o}{.}\PYG{n}{GET}\PYG{p}{)}
\PYG{k}{def} \PYG{n+nf}{root}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{,}\PYG{o}{*}\PYG{o}{*}\PYG{n}{kwargs}\PYG{p}{)}\PYG{p}{:}
\PYG{k}{return} \PYG{n}{request}\PYG{o}{.}\PYG{n}{received\PYGZus{}headers}
\PYG{k}{def} \PYG{n+nf}{run\PYGZus{}filter\PYGZus{}app}\PYG{p}{(}\PYG{p}{)}\PYG{p}{:}
\PYG{n}{app} \PYG{o}{=} \PYG{n}{RESTResource}\PYG{p}{(}\PYG{n}{services}\PYG{o}{=}\PYG{p}{(}\PYG{n}{FilterApp}\PYG{p}{(}\PYG{p}{)}\PYG{p}{,}\PYG{p}{)}\PYG{p}{,}\PYG{n}{filters}\PYG{o}{=}\PYG{p}{(}\PYG{n}{Change404to503Filter}\PYG{p}{(}\PYG{p}{)}\PYG{p}{,}\PYG{n}{AddCustomHeaderFilter}\PYG{p}{(}\PYG{p}{)}\PYG{p}{,}\PYG{n}{WrapAroundFilter}\PYG{p}{(}\PYG{p}{)}\PYG{p}{,}\PYG{p}{)}\PYG{p}{)}
\PYG{n}{app}\PYG{o}{.}\PYG{n}{run}\PYG{p}{(}\PYG{l+m+mi}{8083}\PYG{p}{)}
\end{Verbatim}
\section{HTTP codes}
\label{http_codes::doc}\label{http_codes:http-codes}
By default, CorePost returns the appropriate HTTP code based on the HTTP method:
Success:
\begin{itemize}
\item {}
200 (OK) - GET, DELETE, PUT
\item {}
201 (Created) - POST
\end{itemize}
Errors:
\begin{itemize}
\item {}
404 - not able to match any URL.
\item {}
400 - missing mandatory argument (driven from the arguments on the actual functions)
\item {}
400 - argument failed validation
\item {}
500 - server error
\end{itemize}
\section{Asynchronous Operations}
\label{async:asynchronous-operations}\label{async::doc}
\subsection{@defer.inlineCallbacks support}
\label{async:defer-inlinecallbacks-support}
If you want a deferred async method, just use \emph{defer.returnValue()}:
\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n+nd}{@route}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/}\PYG{l+s}{"}\PYG{p}{,}\PYG{n}{Http}\PYG{o}{.}\PYG{n}{GET}\PYG{p}{)}
\PYG{n+nd}{@defer.inlineCallbacks}
\PYG{k}{def} \PYG{n+nf}{root}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{,}\PYG{o}{*}\PYG{o}{*}\PYG{n}{kwargs}\PYG{p}{)}\PYG{p}{:}
\PYG{n}{val1} \PYG{o}{=} \PYG{k}{yield} \PYG{n}{db}\PYG{o}{.}\PYG{n}{query}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{SELECT ....}\PYG{l+s}{"}\PYG{p}{)}
\PYG{n}{val2} \PYG{o}{=} \PYG{k}{yield} \PYG{n}{db}\PYG{o}{.}\PYG{n}{query}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{SELECT ....}\PYG{l+s}{"}\PYG{p}{)}
\PYG{n}{defer}\PYG{o}{.}\PYG{n}{returnValue}\PYG{p}{(}\PYG{n}{val1} \PYG{o}{+} \PYG{n}{val2}\PYG{p}{)}
\end{Verbatim}
This is standard Twisted functionality.
\section{Modular REST applications}
\label{modules::doc}\label{modules:modular-rest-applications}
A typical case in REST is where you have parent/child resources (business entities), e.g.
......@@ -750,6 +740,87 @@ Here is a full-blown example of two REST services for Customer and Customer Addr
\end{Verbatim}
\section{Filters}
\label{filters::doc}\label{filters:filters}
There is support for CorePost resource filters via the two following \emph{corepost.filter} interfaces:
\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{class} \PYG{n+nc}{IRequestFilter}\PYG{p}{(}\PYG{n}{Interface}\PYG{p}{)}\PYG{p}{:}
\PYG{l+s+sd}{"""Request filter interface"""}
\PYG{k}{def} \PYG{n+nf}{filterRequest}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{)}\PYG{p}{:}
\PYG{l+s+sd}{"""Allows to intercept and change an incoming request"""}
\PYG{k}{pass}
\PYG{k}{class} \PYG{n+nc}{IResponseFilter}\PYG{p}{(}\PYG{n}{Interface}\PYG{p}{)}\PYG{p}{:}
\PYG{l+s+sd}{"""Response filter interface"""}
\PYG{k}{def} \PYG{n+nf}{filterResponse}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{,}\PYG{n}{response}\PYG{p}{)}\PYG{p}{:}
\PYG{l+s+sd}{"""Allows to intercept and change an outgoing response"""}
\PYG{k}{pass}
\end{Verbatim}
A filter class can implement either of them or both (for a wrap around filter), e.g.:
\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{class} \PYG{n+nc}{AddCustomHeaderFilter}\PYG{p}{(}\PYG{p}{)}\PYG{p}{:}
\PYG{l+s+sd}{"""Implements a request filter that adds a custom header to the incoming request"""}
\PYG{n}{zope}\PYG{o}{.}\PYG{n}{interface}\PYG{o}{.}\PYG{n}{implements}\PYG{p}{(}\PYG{n}{IRequestFilter}\PYG{p}{)}
\PYG{k}{def} \PYG{n+nf}{filterRequest}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{)}\PYG{p}{:}
\PYG{n}{request}\PYG{o}{.}\PYG{n}{received\PYGZus{}headers}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{Custom-Header}\PYG{l+s}{"}\PYG{p}{]} \PYG{o}{=} \PYG{l+s}{"}\PYG{l+s}{Custom Header Value}\PYG{l+s}{"}
\PYG{k}{class} \PYG{n+nc}{Change404to503Filter}\PYG{p}{(}\PYG{p}{)}\PYG{p}{:}
\PYG{l+s+sd}{"""Implements just a response filter that changes 404 to 503 statuses"""}
\PYG{n}{zope}\PYG{o}{.}\PYG{n}{interface}\PYG{o}{.}\PYG{n}{implements}\PYG{p}{(}\PYG{n}{IResponseFilter}\PYG{p}{)}
\PYG{k}{def} \PYG{n+nf}{filterResponse}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{,}\PYG{n}{response}\PYG{p}{)}\PYG{p}{:}
\PYG{k}{if} \PYG{n}{response}\PYG{o}{.}\PYG{n}{code} \PYG{o}{==} \PYG{l+m+mi}{404}\PYG{p}{:}
\PYG{n}{response}\PYG{o}{.}\PYG{n}{code} \PYG{o}{=} \PYG{l+m+mi}{503}
\PYG{k}{class} \PYG{n+nc}{WrapAroundFilter}\PYG{p}{(}\PYG{p}{)}\PYG{p}{:}
\PYG{l+s+sd}{"""Implements both types of filters in one class"""}
\PYG{n}{zope}\PYG{o}{.}\PYG{n}{interface}\PYG{o}{.}\PYG{n}{implements}\PYG{p}{(}\PYG{n}{IRequestFilter}\PYG{p}{,}\PYG{n}{IResponseFilter}\PYG{p}{)}
\PYG{k}{def} \PYG{n+nf}{filterRequest}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{)}\PYG{p}{:}
\PYG{n}{request}\PYG{o}{.}\PYG{n}{received\PYGZus{}headers}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{X-Wrap-Input}\PYG{l+s}{"}\PYG{p}{]} \PYG{o}{=} \PYG{l+s}{"}\PYG{l+s}{Input}\PYG{l+s}{"}
\PYG{k}{def} \PYG{n+nf}{filterResponse}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{,}\PYG{n}{response}\PYG{p}{)}\PYG{p}{:}
\PYG{n}{response}\PYG{o}{.}\PYG{n}{headers}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{X-Wrap-Output}\PYG{l+s}{"}\PYG{p}{]} \PYG{o}{=} \PYG{l+s}{"}\PYG{l+s}{Output}\PYG{l+s}{"}
\end{Verbatim}
In order to activate the filters on a RESTResource instance, you need to pass a list of them in the constructor as the \emph{filters} parameter, e.g.:
\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{class} \PYG{n+nc}{FilterApp}\PYG{p}{:}
\PYG{n+nd}{@route}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/}\PYG{l+s}{"}\PYG{p}{,}\PYG{n}{Http}\PYG{o}{.}\PYG{n}{GET}\PYG{p}{)}
\PYG{k}{def} \PYG{n+nf}{root}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{,}\PYG{o}{*}\PYG{o}{*}\PYG{n}{kwargs}\PYG{p}{)}\PYG{p}{:}
\PYG{k}{return} \PYG{n}{request}\PYG{o}{.}\PYG{n}{received\PYGZus{}headers}
\PYG{k}{def} \PYG{n+nf}{run\PYGZus{}filter\PYGZus{}app}\PYG{p}{(}\PYG{p}{)}\PYG{p}{:}
\PYG{n}{app} \PYG{o}{=} \PYG{n}{RESTResource}\PYG{p}{(}\PYG{n}{services}\PYG{o}{=}\PYG{p}{(}\PYG{n}{FilterApp}\PYG{p}{(}\PYG{p}{)}\PYG{p}{,}\PYG{p}{)}\PYG{p}{,}\PYG{n}{filters}\PYG{o}{=}\PYG{p}{(}\PYG{n}{Change404to503Filter}\PYG{p}{(}\PYG{p}{)}\PYG{p}{,}\PYG{n}{AddCustomHeaderFilter}\PYG{p}{(}\PYG{p}{)}\PYG{p}{,}\PYG{n}{WrapAroundFilter}\PYG{p}{(}\PYG{p}{)}\PYG{p}{,}\PYG{p}{)}\PYG{p}{)}
\PYG{n}{app}\PYG{o}{.}\PYG{n}{run}\PYG{p}{(}\PYG{l+m+mi}{8083}\PYG{p}{)}
\end{Verbatim}
\section{Asynchronous Operations}
\label{async:asynchronous-operations}\label{async::doc}
\subsection{@defer.inlineCallbacks support}
\label{async:defer-inlinecallbacks-support}
If you want a deferred async method, just use \emph{defer.returnValue()}:
\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n+nd}{@route}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/}\PYG{l+s}{"}\PYG{p}{,}\PYG{n}{Http}\PYG{o}{.}\PYG{n}{GET}\PYG{p}{)}
\PYG{n+nd}{@defer.inlineCallbacks}
\PYG{k}{def} \PYG{n+nf}{root}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{,}\PYG{o}{*}\PYG{o}{*}\PYG{n}{kwargs}\PYG{p}{)}\PYG{p}{:}
\PYG{n}{val1} \PYG{o}{=} \PYG{k}{yield} \PYG{n}{db}\PYG{o}{.}\PYG{n}{query}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{SELECT ....}\PYG{l+s}{"}\PYG{p}{)}
\PYG{n}{val2} \PYG{o}{=} \PYG{k}{yield} \PYG{n}{db}\PYG{o}{.}\PYG{n}{query}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{SELECT ....}\PYG{l+s}{"}\PYG{p}{)}
\PYG{n}{defer}\PYG{o}{.}\PYG{n}{returnValue}\PYG{p}{(}\PYG{n}{val1} \PYG{o}{+} \PYG{n}{val2}\PYG{p}{)}
\end{Verbatim}
This is standard Twisted functionality.
\renewcommand{\indexname}{Index}
\printindex
......
......@@ -17,11 +17,15 @@
\contentsline {subsection}{\numberline {2.2.4}YAML document arguments}{5}{subsection.2.2.4}
\contentsline {subsection}{\numberline {2.2.5}XML document arguments}{5}{subsection.2.2.5}
\contentsline {section}{\numberline {2.3}Argument validation}{6}{section.2.3}
\contentsline {section}{\numberline {2.4}Content types}{6}{section.2.4}
\contentsline {subsection}{\numberline {2.4.1}Parsing of incoming content}{6}{subsection.2.4.1}
\contentsline {subsection}{\numberline {2.4.2}Converting Python objects to expected content type}{7}{subsection.2.4.2}
\contentsline {section}{\numberline {2.5}Filters}{7}{section.2.5}
\contentsline {section}{\numberline {2.6}HTTP codes}{8}{section.2.6}
\contentsline {section}{\numberline {2.7}Asynchronous Operations}{8}{section.2.7}
\contentsline {subsection}{\numberline {2.7.1}@defer.inlineCallbacks support}{8}{subsection.2.7.1}
\contentsline {section}{\numberline {2.8}Modular REST applications}{9}{section.2.8}
\contentsline {section}{\numberline {2.4}HTTP codes}{6}{section.2.4}
\contentsline {section}{\numberline {2.5}Returning responses}{7}{section.2.5}
\contentsline {subsection}{\numberline {2.5.1}String}{7}{subsection.2.5.1}
\contentsline {subsection}{\numberline {2.5.2}Dictionaries, lists or classes}{7}{subsection.2.5.2}
\contentsline {subsection}{\numberline {2.5.3}Response objects}{7}{subsection.2.5.3}
\contentsline {section}{\numberline {2.6}Content types}{8}{section.2.6}
\contentsline {subsection}{\numberline {2.6.1}Parsing of incoming content}{8}{subsection.2.6.1}
\contentsline {subsection}{\numberline {2.6.2}Converting Python objects to expected content type}{8}{subsection.2.6.2}
\contentsline {section}{\numberline {2.7}Modular REST applications}{8}{section.2.7}
\contentsline {section}{\numberline {2.8}Filters}{11}{section.2.8}
\contentsline {section}{\numberline {2.9}Asynchronous Operations}{12}{section.2.9}
\contentsline {subsection}{\numberline {2.9.1}@defer.inlineCallbacks support}{12}{subsection.2.9.1}
......@@ -49,9 +49,9 @@ copyright = u'2012, Jacek Furmankiewicz'
# built documents.
#
# The short X.Y version.
version = '0.0.14'
version = '0.1'
# The full version, including alpha/beta/rc tags.
release = '0.0.14'
release = '0.0.16'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
......
......@@ -18,9 +18,10 @@ Features
url_routing
argument_parsing
arguments
http_codes
responses
content_types
modules
filters
http_codes
async
modules
Returning responses
===================
There are a number of ways in which you can return a response from a REST service
String
------
You can simply return a plain text String. CorePost will return the appropriate HTTP code for you::
@route("/",Http.GET)
def root(self,request,**kwargs):
return "Hello"
Dictionaries, lists or classes
------------------------------
You can return straight dictionaries::
@route("/",Http.GET)
def root(self,request,**kwargs):
return {"test":"test"}
or lists::
@route("/",Http.GET)
def root(self,request,**kwargs):
return [{"test":"test"},{"test":"test2"}]
or classes::
@route("/",Http.GET)
def root(self,request,**kwargs):
return SomeClass()
CorePost will serialize each of them to the appropriate content type (JSON,YAML or XML), depending on what the caller can accept.
Response objects
----------------
This option gives you the most control, as you can explicitly specify the response content, headers and HTTP code.
You need to return an instance of *corepost.Response* object::
class Response:
"""
Custom response object, can be returned instead of raw string response
"""
def __init__(self,code=200,entity=None,headers={}):
pass
Example::
@route("/",Http.POST)
def post(self,request,customerId,addressId,streetNumber,streetName,stateCode,countryCode):
c = DB.getCustomer(customerId)
address = CustomerAddress(streetNumber,streetName,stateCode,countryCode)
c.addresses[addressId] = address
return Response(201)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment