Commit 37c45a3b authored by Jacek Furmankiewicz's avatar Jacek Furmankiewicz

docs for argument parsing

parent a7a26a6a
...@@ -12,15 +12,11 @@ from corepost.convert import convertForSerialization, generateXml ...@@ -12,15 +12,11 @@ from corepost.convert import convertForSerialization, generateXml
from corepost.filters import IRequestFilter, IResponseFilter from corepost.filters import IRequestFilter, IResponseFilter
from enums import MediaType from enums import MediaType
from twisted.internet import reactor, defer from twisted.internet import defer
from twisted.web.http import parse_qs from twisted.web.http import parse_qs
from twisted.web.resource import Resource
from twisted.web.server import Site, NOT_DONE_YET
from twisted.python import log from twisted.python import log
import re, copy, exceptions, json, yaml, logging import re, copy, exceptions, json, yaml, logging
from xml.etree import ElementTree from xml.etree import ElementTree
from xml.etree.ElementTree import Element
from zope.interface.verify import verifyObject
class UrlRouter: class UrlRouter:
''' Common class for containing info related to routing a request to a function ''' ''' Common class for containing info related to routing a request to a function '''
......
...@@ -28,6 +28,10 @@ class ArgumentApp(): ...@@ -28,6 +28,10 @@ class ArgumentApp():
def postValidateCustom(self,request,rootId,childId,**kwargs): def postValidateCustom(self,request,rootId,childId,**kwargs):
return "%s - %s - %s" % (rootId,childId,kwargs) return "%s - %s - %s" % (rootId,childId,kwargs)
@route("/formOrJson",Http.GET)
def getArgumentsByContentType(self,request,first,last,**kwargs):
return "%s %s" % (str(first),str(last))
@route("/formOrJson",(Http.POST,Http.PUT)) @route("/formOrJson",(Http.POST,Http.PUT))
def postArgumentsByContentType(self,request,first,last,**kwargs): def postArgumentsByContentType(self,request,first,last,**kwargs):
return "%s %s" % (str(first),str(last)) return "%s %s" % (str(first),str(last))
......
...@@ -105,3 +105,9 @@ last: Gingrychnoya ...@@ -105,3 +105,9 @@ last: Gingrychnoya
| POST | 201 | | POST | 201 |
| PUT | 200 | | PUT | 200 |
@arguments_by_type
Scenario: Parse query arguments for GET
Given 'arguments' is running
When as user 'None:None' I GET 'http://127.0.0.1:8082/formOrJson?first=John&last=Doe'
Then I expect HTTP code 200
And I expect content contains 'John Doe'
Asynchronous Operations Asynchronous Operations
================= =======================
@defer.inlineCallbacks support @defer.inlineCallbacks support
----------------------- ------------------------------
If you want a deferred async method, just use *defer.returnValue()*:: If you want a deferred async method, just use *defer.returnValue()*::
......
...@@ -16,9 +16,11 @@ Features ...@@ -16,9 +16,11 @@ Features
:maxdepth: 4 :maxdepth: 4
url_routing url_routing
argument_parsing
arguments arguments
content_types content_types
filters filters
http_codes http_codes
async async
modules modules
...@@ -42,7 +42,7 @@ based on URL (with dynamic paths), HTTP method, expected content type, etc:: ...@@ -42,7 +42,7 @@ based on URL (with dynamic paths), HTTP method, expected content type, etc::
* http://twistedmatrix.com/documents/current/core/howto/tap.html * http://twistedmatrix.com/documents/current/core/howto/tap.html
Path argument extraction Path argument extraction
---------------- ------------------------
CorePort can easily extract path arguments from an URL and convert them to the desired type. CorePort can easily extract path arguments from an URL and convert them to the desired type.
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
<script type="text/javascript" src="_static/doctools.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.14 documentation" href="index.html" />
<link rel="next" title="Content types" href="content_types.html" /> <link rel="next" title="Content types" href="content_types.html" />
<link rel="prev" title="URL Routing" href="url_routing.html" /> <link rel="prev" title="Argument parsing" href="argument_parsing.html" />
</head> </head>
<body> <body>
<div class="related"> <div class="related">
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
<a href="content_types.html" title="Content types" <a href="content_types.html" title="Content types"
accesskey="N">next</a> |</li> accesskey="N">next</a> |</li>
<li class="right" > <li class="right" >
<a href="url_routing.html" title="URL Routing" <a href="argument_parsing.html" title="Argument parsing"
accesskey="P">previous</a> |</li> 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.14 documentation</a> &raquo;</li>
</ul> </ul>
...@@ -95,8 +95,8 @@ Validators can be specified using a <em>formencode</em> Schema object, or via cu ...@@ -95,8 +95,8 @@ Validators can be specified using a <em>formencode</em> Schema object, or via cu
<div class="sphinxsidebar"> <div class="sphinxsidebar">
<div class="sphinxsidebarwrapper"> <div class="sphinxsidebarwrapper">
<h4>Previous topic</h4> <h4>Previous topic</h4>
<p class="topless"><a href="url_routing.html" <p class="topless"><a href="argument_parsing.html"
title="previous chapter">URL Routing</a></p> title="previous chapter">Argument parsing</a></p>
<h4>Next topic</h4> <h4>Next topic</h4>
<p class="topless"><a href="content_types.html" <p class="topless"><a href="content_types.html"
title="next chapter">Content types</a></p> title="next chapter">Content types</a></p>
...@@ -132,7 +132,7 @@ Validators can be specified using a <em>formencode</em> Schema object, or via cu ...@@ -132,7 +132,7 @@ Validators can be specified using a <em>formencode</em> Schema object, or via cu
<a href="content_types.html" title="Content types" <a href="content_types.html" title="Content types"
>next</a> |</li> >next</a> |</li>
<li class="right" > <li class="right" >
<a href="url_routing.html" title="URL Routing" <a href="argument_parsing.html" title="Argument parsing"
>previous</a> |</li> >previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li> <li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
</ul> </ul>
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
<script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.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.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="prev" title="HTTP codes" href="http_codes.html" />
</head> </head>
<body> <body>
...@@ -35,6 +36,9 @@ ...@@ -35,6 +36,9 @@
<li class="right" style="margin-right: 10px"> <li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index" <a href="genindex.html" title="General Index"
accesskey="I">index</a></li> accesskey="I">index</a></li>
<li class="right" >
<a href="modules.html" title="Modular REST applications"
accesskey="N">next</a> |</li>
<li class="right" > <li class="right" >
<a href="http_codes.html" title="HTTP codes" <a href="http_codes.html" title="HTTP codes"
accesskey="P">previous</a> |</li> accesskey="P">previous</a> |</li>
...@@ -81,6 +85,9 @@ ...@@ -81,6 +85,9 @@
<h4>Previous topic</h4> <h4>Previous topic</h4>
<p class="topless"><a href="http_codes.html" <p class="topless"><a href="http_codes.html"
title="previous chapter">HTTP codes</a></p> 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>
<h3>This Page</h3> <h3>This Page</h3>
<ul class="this-page-menu"> <ul class="this-page-menu">
<li><a href="_sources/async.txt" <li><a href="_sources/async.txt"
...@@ -109,6 +116,9 @@ ...@@ -109,6 +116,9 @@
<li class="right" style="margin-right: 10px"> <li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index" <a href="genindex.html" title="General Index"
>index</a></li> >index</a></li>
<li class="right" >
<a href="modules.html" title="Modular REST applications"
>next</a> |</li>
<li class="right" > <li class="right" >
<a href="http_codes.html" title="HTTP codes" <a href="http_codes.html" title="HTTP codes"
>previous</a> |</li> >previous</a> |</li>
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
<script type="text/javascript" src="_static/doctools.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.14 documentation" href="index.html" />
<link rel="next" title="Asynchronous Operations" href="async.html" /> <link rel="next" title="Asynchronous Operations" href="async.html" />
<link rel="prev" title="Modular REST applications" href="modules.html" /> <link rel="prev" title="Filters" href="filters.html" />
</head> </head>
<body> <body>
<div class="related"> <div class="related">
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
<a href="async.html" title="Asynchronous Operations" <a href="async.html" title="Asynchronous Operations"
accesskey="N">next</a> |</li> accesskey="N">next</a> |</li>
<li class="right" > <li class="right" >
<a href="modules.html" title="Modular REST applications" <a href="filters.html" title="Filters"
accesskey="P">previous</a> |</li> 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.14 documentation</a> &raquo;</li>
</ul> </ul>
...@@ -75,8 +75,8 @@ ...@@ -75,8 +75,8 @@
<div class="sphinxsidebar"> <div class="sphinxsidebar">
<div class="sphinxsidebarwrapper"> <div class="sphinxsidebarwrapper">
<h4>Previous topic</h4> <h4>Previous topic</h4>
<p class="topless"><a href="modules.html" <p class="topless"><a href="filters.html"
title="previous chapter">Modular REST applications</a></p> title="previous chapter">Filters</a></p>
<h4>Next topic</h4> <h4>Next topic</h4>
<p class="topless"><a href="async.html" <p class="topless"><a href="async.html"
title="next chapter">Asynchronous Operations</a></p> title="next chapter">Asynchronous Operations</a></p>
...@@ -112,7 +112,7 @@ ...@@ -112,7 +112,7 @@
<a href="async.html" title="Asynchronous Operations" <a href="async.html" title="Asynchronous Operations"
>next</a> |</li> >next</a> |</li>
<li class="right" > <li class="right" >
<a href="modules.html" title="Modular REST applications" <a href="filters.html" title="Filters"
>previous</a> |</li> >previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li> <li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
</ul> </ul>
......
...@@ -73,6 +73,14 @@ ...@@ -73,6 +73,14 @@
<li class="toctree-l2"><a class="reference internal" href="url_routing.html#routing-requests-by-incoming-content-type">Routing requests by incoming content type</a></li> <li class="toctree-l2"><a class="reference internal" href="url_routing.html#routing-requests-by-incoming-content-type">Routing requests by incoming content type</a></li>
</ul> </ul>
</li> </li>
<li class="toctree-l1"><a class="reference internal" href="argument_parsing.html">Argument parsing</a><ul>
<li class="toctree-l2"><a class="reference internal" href="argument_parsing.html#query-arguments">Query arguments</a></li>
<li class="toctree-l2"><a class="reference internal" href="argument_parsing.html#form-encoded-arguments">Form encoded arguments</a></li>
<li class="toctree-l2"><a class="reference internal" href="argument_parsing.html#json-document-arguments">JSON document arguments</a></li>
<li class="toctree-l2"><a class="reference internal" href="argument_parsing.html#yaml-document-arguments">YAML document arguments</a></li>
<li class="toctree-l2"><a class="reference internal" href="argument_parsing.html#xml-document-arguments">XML document arguments</a></li>
</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="arguments.html">Argument validation</a></li>
<li class="toctree-l1"><a class="reference internal" href="content_types.html">Content types</a><ul> <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#parsing-of-incoming-content">Parsing of incoming content</a></li>
......
...@@ -26,8 +26,7 @@ ...@@ -26,8 +26,7 @@
<script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.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.14 documentation" href="index.html" />
<link rel="next" title="HTTP codes" href="http_codes.html" /> <link rel="prev" title="Asynchronous Operations" href="async.html" />
<link rel="prev" title="Argument validation" href="arguments.html" />
</head> </head>
<body> <body>
<div class="related"> <div class="related">
...@@ -37,10 +36,7 @@ ...@@ -37,10 +36,7 @@
<a href="genindex.html" title="General Index" <a href="genindex.html" title="General Index"
accesskey="I">index</a></li> accesskey="I">index</a></li>
<li class="right" > <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="arguments.html" title="Argument validation"
accesskey="P">previous</a> |</li> 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.14 documentation</a> &raquo;</li>
</ul> </ul>
...@@ -184,11 +180,8 @@ and it takes care of routing the request to the appropriate class.</p> ...@@ -184,11 +180,8 @@ and it takes care of routing the request to the appropriate class.</p>
<div class="sphinxsidebar"> <div class="sphinxsidebar">
<div class="sphinxsidebarwrapper"> <div class="sphinxsidebarwrapper">
<h4>Previous topic</h4> <h4>Previous topic</h4>
<p class="topless"><a href="arguments.html" <p class="topless"><a href="async.html"
title="previous chapter">Argument validation</a></p> title="previous chapter">Asynchronous Operations</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="http_codes.html"
title="next chapter">HTTP codes</a></p>
<h3>This Page</h3> <h3>This Page</h3>
<ul class="this-page-menu"> <ul class="this-page-menu">
<li><a href="_sources/modules.txt" <li><a href="_sources/modules.txt"
...@@ -218,10 +211,7 @@ and it takes care of routing the request to the appropriate class.</p> ...@@ -218,10 +211,7 @@ and it takes care of routing the request to the appropriate class.</p>
<a href="genindex.html" title="General Index" <a href="genindex.html" title="General Index"
>index</a></li> >index</a></li>
<li class="right" > <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="arguments.html" title="Argument validation"
>previous</a> |</li> >previous</a> |</li>
<li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li> <li><a href="index.html">CorePost 0.0.14 documentation</a> &raquo;</li>
</ul> </ul>
......
This diff is collapsed.
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
<script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.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.14 documentation" href="index.html" />
<link rel="next" title="Argument validation" href="arguments.html" /> <link rel="next" title="Argument parsing" href="argument_parsing.html" />
<link rel="prev" title="Introduction" href="intro.html" /> <link rel="prev" title="Introduction" href="intro.html" />
</head> </head>
<body> <body>
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
<a href="genindex.html" title="General Index" <a href="genindex.html" title="General Index"
accesskey="I">index</a></li> accesskey="I">index</a></li>
<li class="right" > <li class="right" >
<a href="arguments.html" title="Argument validation" <a href="argument_parsing.html" title="Argument parsing"
accesskey="N">next</a> |</li> accesskey="N">next</a> |</li>
<li class="right" > <li class="right" >
<a href="intro.html" title="Introduction" <a href="intro.html" title="Introduction"
...@@ -153,8 +153,8 @@ In a real production application you would use existing Twisted <em>twistd</em> ...@@ -153,8 +153,8 @@ In a real production application you would use existing Twisted <em>twistd</em>
<p class="topless"><a href="intro.html" <p class="topless"><a href="intro.html"
title="previous chapter">Introduction</a></p> title="previous chapter">Introduction</a></p>
<h4>Next topic</h4> <h4>Next topic</h4>
<p class="topless"><a href="arguments.html" <p class="topless"><a href="argument_parsing.html"
title="next chapter">Argument validation</a></p> title="next chapter">Argument parsing</a></p>
<h3>This Page</h3> <h3>This Page</h3>
<ul class="this-page-menu"> <ul class="this-page-menu">
<li><a href="_sources/url_routing.txt" <li><a href="_sources/url_routing.txt"
...@@ -184,7 +184,7 @@ In a real production application you would use existing Twisted <em>twistd</em> ...@@ -184,7 +184,7 @@ In a real production application you would use existing Twisted <em>twistd</em>
<a href="genindex.html" title="General Index" <a href="genindex.html" title="General Index"
>index</a></li> >index</a></li>
<li class="right" > <li class="right" >
<a href="arguments.html" title="Argument validation" <a href="argument_parsing.html" title="Argument parsing"
>next</a> |</li> >next</a> |</li>
<li class="right" > <li class="right" >
<a href="intro.html" title="Introduction" <a href="intro.html" title="Introduction"
......
...@@ -45,27 +45,40 @@ ...@@ -45,27 +45,40 @@
\newlabel{url_routing:path-argument-extraction}{{2.1.2}{4}{Path argument extraction\relax }{subsection.2.1.2}{}} \newlabel{url_routing:path-argument-extraction}{{2.1.2}{4}{Path argument extraction\relax }{subsection.2.1.2}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.1.3}Routing requests by incoming content type}{4}{subsection.2.1.3}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.1.3}Routing requests by incoming content type}{4}{subsection.2.1.3}}
\newlabel{url_routing:routing-requests-by-incoming-content-type}{{2.1.3}{4}{Routing requests by incoming content type\relax }{subsection.2.1.3}{}} \newlabel{url_routing:routing-requests-by-incoming-content-type}{{2.1.3}{4}{Routing requests by incoming content type\relax }{subsection.2.1.3}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.2}Argument validation}{4}{section.2.2}} \@writefile{toc}{\contentsline {section}{\numberline {2.2}Argument parsing}{4}{section.2.2}}
\newlabel{arguments:argument-validation}{{2.2}{4}{Argument validation\relax }{section.2.2}{}} \newlabel{argument_parsing::doc}{{2.2}{4}{Argument parsing\relax }{section.2.2}{}}
\newlabel{arguments::doc}{{2.2}{4}{Argument validation\relax }{section.2.2}{}} \newlabel{argument_parsing:argument-parsing}{{2.2}{4}{Argument parsing\relax }{section.2.2}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.3}Content types}{5}{section.2.3}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.2.1}Query arguments}{4}{subsection.2.2.1}}
\newlabel{content_types::doc}{{2.3}{5}{Content types\relax }{section.2.3}{}} \newlabel{argument_parsing:query-arguments}{{2.2.1}{4}{Query arguments\relax }{subsection.2.2.1}{}}
\newlabel{content_types:content-types}{{2.3}{5}{Content types\relax }{section.2.3}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.2.2}Form encoded arguments}{5}{subsection.2.2.2}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.1}Parsing of incoming content}{5}{subsection.2.3.1}} \newlabel{argument_parsing:form-encoded-arguments}{{2.2.2}{5}{Form encoded arguments\relax }{subsection.2.2.2}{}}
\newlabel{content_types:parsing-of-incoming-content}{{2.3.1}{5}{Parsing of incoming content\relax }{subsection.2.3.1}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.2.3}JSON document arguments}{5}{subsection.2.2.3}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.2}Converting Python objects to expected content type}{5}{subsection.2.3.2}} \newlabel{argument_parsing:json-document-arguments}{{2.2.3}{5}{JSON document arguments\relax }{subsection.2.2.3}{}}
\newlabel{content_types:converting-python-objects-to-expected-content-type}{{2.3.2}{5}{Converting Python objects to expected content type\relax }{subsection.2.3.2}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.2.4}YAML document arguments}{5}{subsection.2.2.4}}
\@writefile{toc}{\contentsline {section}{\numberline {2.4}Filters}{6}{section.2.4}} \newlabel{argument_parsing:yaml-document-arguments}{{2.2.4}{5}{YAML document arguments\relax }{subsection.2.2.4}{}}
\newlabel{filters::doc}{{2.4}{6}{Filters\relax }{section.2.4}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.2.5}XML document arguments}{5}{subsection.2.2.5}}
\newlabel{filters:filters}{{2.4}{6}{Filters\relax }{section.2.4}{}} \newlabel{argument_parsing:xml-document-arguments}{{2.2.5}{5}{XML document arguments\relax }{subsection.2.2.5}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.5}HTTP codes}{7}{section.2.5}} \@writefile{toc}{\contentsline {section}{\numberline {2.3}Argument validation}{6}{section.2.3}}
\newlabel{http_codes::doc}{{2.5}{7}{HTTP codes\relax }{section.2.5}{}} \newlabel{arguments:argument-validation}{{2.3}{6}{Argument validation\relax }{section.2.3}{}}
\newlabel{http_codes:http-codes}{{2.5}{7}{HTTP codes\relax }{section.2.5}{}} \newlabel{arguments::doc}{{2.3}{6}{Argument validation\relax }{section.2.3}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.6}Asynchronous Operations}{7}{section.2.6}} \@writefile{toc}{\contentsline {section}{\numberline {2.4}Content types}{6}{section.2.4}}
\newlabel{async:asynchronous-operations}{{2.6}{7}{Asynchronous Operations\relax }{section.2.6}{}} \newlabel{content_types::doc}{{2.4}{6}{Content types\relax }{section.2.4}{}}
\newlabel{async::doc}{{2.6}{7}{Asynchronous Operations\relax }{section.2.6}{}} \newlabel{content_types:content-types}{{2.4}{6}{Content types\relax }{section.2.4}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.6.1}@defer.inlineCallbacks support}{7}{subsection.2.6.1}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.4.1}Parsing of incoming content}{6}{subsection.2.4.1}}
\newlabel{async:defer-inlinecallbacks-support}{{2.6.1}{7}{@defer.inlineCallbacks support\relax }{subsection.2.6.1}{}} \newlabel{content_types:parsing-of-incoming-content}{{2.4.1}{6}{Parsing of incoming content\relax }{subsection.2.4.1}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2.7}Modular REST applications}{7}{section.2.7}} \@writefile{toc}{\contentsline {subsection}{\numberline {2.4.2}Converting Python objects to expected content type}{7}{subsection.2.4.2}}
\newlabel{modules::doc}{{2.7}{7}{Modular REST applications\relax }{section.2.7}{}} \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}{}}
\newlabel{modules:modular-rest-applications}{{2.7}{7}{Modular REST applications\relax }{section.2.7}{}} \@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}{}}
This is pdfTeX, Version 3.1415926-1.40.10 (TeX Live 2009/Debian) (format=pdflatex 2012.2.29) 8 MAR 2012 10:07 This is pdfTeX, Version 3.1415926-1.40.10 (TeX Live 2009/Debian) (format=pdflatex 2012.2.29) 19 MAR 2012 13:29
entering extended mode entering extended mode
%&-line parsing enabled. %&-line parsing enabled.
**CorePost.tex **CorePost.tex
...@@ -903,34 +903,34 @@ LaTeX Font Info: Font shape `T1/pcr/m/it' in size <9> not available ...@@ -903,34 +903,34 @@ LaTeX Font Info: Font shape `T1/pcr/m/it' in size <9> not available
[3 [3
] [4] [5] [6] [7] ] [4] [5] [6] [7]
[8] [8] [9]
Underfull \vbox (badness 10000) detected at line 656 Underfull \vbox (badness 10000) detected at line 750
[] []
Underfull \vbox (badness 10000) detected at line 656 Underfull \vbox (badness 10000) detected at line 750
[] []
[9] (./CorePost.ind) [10] (./CorePost.aux) ) [10] (./CorePost.ind) [11] (./CorePost.aux) )
Here is how much of TeX's memory you used: Here is how much of TeX's memory you used:
7966 strings out of 493848 7981 strings out of 493848
107801 string characters out of 1152823 108170 string characters out of 1152823
197135 words of memory out of 3000000 197503 words of memory out of 3000000
11011 multiletter control sequences out of 15000+50000 11019 multiletter control sequences out of 15000+50000
55793 words of font info for 63 fonts, out of 3000000 for 9000 55793 words of font info for 63 fonts, out of 3000000 for 9000
715 hyphenation exceptions out of 8191 715 hyphenation exceptions out of 8191
45i,12n,45p,426b,381s stack positions out of 5000i,500n,10000p,200000b,50000s 45i,12n,45p,426b,381s stack positions out of 5000i,500n,10000p,200000b,50000s
{/usr/share/texmf-texlive/fonts/enc {/usr/share/texmf-texlive/fonts/en
/dvips/base/8r.enc}</usr/share/texmf-texlive/fonts/type1/urw/courier/ucrb8a.pfb c/dvips/base/8r.enc}</usr/share/texmf-texlive/fonts/type1/urw/courier/ucrb8a.pf
></usr/share/texmf-texlive/fonts/type1/urw/courier/ucrr8a.pfb></usr/share/texmf b></usr/share/texmf-texlive/fonts/type1/urw/courier/ucrr8a.pfb></usr/share/texm
-texlive/fonts/type1/urw/courier/ucrro8a.pfb></usr/share/texmf-texlive/fonts/ty f-texlive/fonts/type1/urw/courier/ucrro8a.pfb></usr/share/texmf-texlive/fonts/t
pe1/urw/helvetic/uhvb8a.pfb></usr/share/texmf-texlive/fonts/type1/urw/helvetic/ 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/sh /uhvbo8a.pfb></usr/share/texmf-texlive/fonts/type1/urw/times/utmb8a.pfb></usr/s
are/texmf-texlive/fonts/type1/urw/times/utmr8a.pfb></usr/share/texmf-texlive/fo hare/texmf-texlive/fonts/type1/urw/times/utmr8a.pfb></usr/share/texmf-texlive/f
nts/type1/urw/times/utmri8a.pfb> onts/type1/urw/times/utmri8a.pfb>
Output written on CorePost.pdf (14 pages, 143233 bytes). Output written on CorePost.pdf (15 pages, 149329 bytes).
PDF statistics: PDF statistics:
175 PDF objects out of 1000 (max. 8388607) 192 PDF objects out of 1000 (max. 8388607)
35 named destinations out of 1000 (max. 500000) 42 named destinations out of 1000 (max. 500000)
81 words of extra memory for PDF output out of 10000 (max. 10000000) 89 words of extra memory for PDF output out of 10000 (max. 10000000)
...@@ -2,9 +2,10 @@ ...@@ -2,9 +2,10 @@
\BOOKMARK [1][-]{section.1.1}{Introduction}{chapter.1} \BOOKMARK [1][-]{section.1.1}{Introduction}{chapter.1}
\BOOKMARK [0][-]{chapter.2}{Features}{} \BOOKMARK [0][-]{chapter.2}{Features}{}
\BOOKMARK [1][-]{section.2.1}{URL Routing}{chapter.2} \BOOKMARK [1][-]{section.2.1}{URL Routing}{chapter.2}
\BOOKMARK [1][-]{section.2.2}{Argument validation}{chapter.2} \BOOKMARK [1][-]{section.2.2}{Argument parsing}{chapter.2}
\BOOKMARK [1][-]{section.2.3}{Content types}{chapter.2} \BOOKMARK [1][-]{section.2.3}{Argument validation}{chapter.2}
\BOOKMARK [1][-]{section.2.4}{Filters}{chapter.2} \BOOKMARK [1][-]{section.2.4}{Content types}{chapter.2}
\BOOKMARK [1][-]{section.2.5}{HTTP codes}{chapter.2} \BOOKMARK [1][-]{section.2.5}{Filters}{chapter.2}
\BOOKMARK [1][-]{section.2.6}{Asynchronous Operations}{chapter.2} \BOOKMARK [1][-]{section.2.6}{HTTP codes}{chapter.2}
\BOOKMARK [1][-]{section.2.7}{Modular REST applications}{chapter.2} \BOOKMARK [1][-]{section.2.7}{Asynchronous Operations}{chapter.2}
\BOOKMARK [1][-]{section.2.8}{Modular REST applications}{chapter.2}
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
\title{CorePost Documentation} \title{CorePost Documentation}
\date{March 08, 2012} \date{March 19, 2012}
\release{0.0.14} \release{0.0.14}
\author{Jacek Furmankiewicz} \author{Jacek Furmankiewicz}
\newcommand{\sphinxlogo}{} \newcommand{\sphinxlogo}{}
...@@ -298,6 +298,100 @@ Based on the incoming content type in POST/PUT requests, the \emph{same} URL can ...@@ -298,6 +298,100 @@ Based on the incoming content type in POST/PUT requests, the \emph{same} URL can
\end{Verbatim} \end{Verbatim}
\section{Argument parsing}
\label{argument_parsing::doc}\label{argument_parsing:argument-parsing}
CorePost can automatically parse query arguments, form arguments, as well as basic JSON, YAML and XML documents
and extract those as direct arguments to a REST router method.
Let's say we have a basic method that responds to GET, POST and PUT requests.
It expects a first name and last name and outputs them back in the response:
\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n+nd}{@router}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/name}\PYG{l+s}{"}\PYG{p}{,}\PYG{p}{(}\PYG{n}{Http}\PYG{o}{.}\PYG{n}{GET}\PYG{p}{,}\PYG{n}{Http}\PYG{o}{.}\PYG{n}{POST}\PYG{p}{,}\PYG{n}{Http}\PYG{o}{.}\PYG{n}{PUT}\PYG{p}{)}\PYG{p}{)}
\PYG{k}{def} \PYG{n+nf}{getName}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{request}\PYG{p}{,}\PYG{n}{first}\PYG{p}{,}\PYG{n}{last}\PYG{p}{,}\PYG{o}{*}\PYG{o}{*}\PYG{n}{kwargs}\PYG{p}{)}\PYG{p}{:}
\PYG{k}{return} \PYG{l+s}{"}\PYG{l+s+si}{\PYGZpc{}s}\PYG{l+s}{ }\PYG{l+s+si}{\PYGZpc{}s}\PYG{l+s}{"} \PYG{o}{\PYGZpc{}} \PYG{p}{(}\PYG{n}{first}\PYG{p}{,} \PYG{n}{last}\PYG{p}{)}
\end{Verbatim}
\subsection{Query arguments}
\label{argument_parsing:query-arguments}
For GET requests, the query arguments will be automatically parsed, e.g.:
\begin{Verbatim}[commandchars=\\\{\}]
curl http://127.0.0.1/name?first=John\&last=Doe
\end{Verbatim}
\subsection{Form encoded arguments}
\label{argument_parsing:form-encoded-arguments}
For POST/PUT requests, any form-encoded arguments will be automatically parsed, e.g.:
\begin{Verbatim}[commandchars=\\\{\}]
curl -X POST http://localhost/name -d "first=John\&last=Doe"
\end{Verbatim}
\subsection{JSON document arguments}
\label{argument_parsing:json-document-arguments}
For the same method, you could just post a JSON document instead that looks like this:
\begin{Verbatim}[commandchars=\\\{\}]
\PYG{p}{\PYGZob{}}\PYG{l+s}{"}\PYG{l+s}{first}\PYG{l+s}{"}\PYG{p}{:}\PYG{l+s}{"}\PYG{l+s}{John}\PYG{l+s}{"}\PYG{p}{,}\PYG{l+s}{"}\PYG{l+s}{last}\PYG{l+s}{"}\PYG{p}{:}\PYG{l+s}{"}\PYG{l+s}{Doe}\PYG{l+s}{"}\PYG{p}{\PYGZcb{}}
\end{Verbatim}
CorePost will automatically pass all the root elements of the document as arguments into a method.
Requires the \emph{`application/json'} content type to be passed.
\subsection{YAML document arguments}
\label{argument_parsing:yaml-document-arguments}
For the same method, you could just post a YAML document that looks like this:
\begin{Verbatim}[commandchars=\\\{\}]
first:John
last:Doe
\end{Verbatim}
CorePost will automatically pass all the root elements of the document as arguments into a method.
Requires the \emph{`text/yaml'} content type to be passed.
\subsection{XML document arguments}
\label{argument_parsing:xml-document-arguments}
XML documents are supported as well. In that case, CorePost will first parse all the attributes on the root node
and then all of the children underneath the main root node.
Hence all of the XML formats below are valid and would generate the same parameters to a method.
Attributes only:
\begin{Verbatim}[commandchars=\\\{\}]
\textless{}root first="John" last="Doe"/\textgreater{}
\end{Verbatim}
Mix of attributes and child nodes:
\begin{Verbatim}[commandchars=\\\{\}]
\textless{}root first="John"\textgreater{}
\textless{}last\textgreater{}Doe\textless{}/last\textgreater{}
\textless{}/root\textgreater{}
\end{Verbatim}
Child nodes only:
\begin{Verbatim}[commandchars=\\\{\}]
\textless{}root\textgreater{}
\textless{}first\textgreater{}John\textless{}/first\textgreater{}
\textless{}last\textgreater{}Doe\textless{}/last\textgreater{}
\textless{}/root\textgreater{}
\end{Verbatim}
Requires the \emph{`text/xml'} OR \emph{`application/xml'} content type to be passed.
As you can see from the examples above, a single CorePost router method can handle all these varied forms of argument parsing
for you without any additional effort.
\section{Argument validation} \section{Argument validation}
\label{arguments:argument-validation}\label{arguments::doc} \label{arguments:argument-validation}\label{arguments::doc}
CorePost integrates the popular `formencode' package to implement form and query argument validation. CorePost integrates the popular `formencode' package to implement form and query argument validation.
......
...@@ -10,12 +10,18 @@ ...@@ -10,12 +10,18 @@
\contentsline {subsection}{\numberline {2.1.1}@route decorator}{3}{subsection.2.1.1} \contentsline {subsection}{\numberline {2.1.1}@route decorator}{3}{subsection.2.1.1}
\contentsline {subsection}{\numberline {2.1.2}Path argument extraction}{4}{subsection.2.1.2} \contentsline {subsection}{\numberline {2.1.2}Path argument extraction}{4}{subsection.2.1.2}
\contentsline {subsection}{\numberline {2.1.3}Routing requests by incoming content type}{4}{subsection.2.1.3} \contentsline {subsection}{\numberline {2.1.3}Routing requests by incoming content type}{4}{subsection.2.1.3}
\contentsline {section}{\numberline {2.2}Argument validation}{4}{section.2.2} \contentsline {section}{\numberline {2.2}Argument parsing}{4}{section.2.2}
\contentsline {section}{\numberline {2.3}Content types}{5}{section.2.3} \contentsline {subsection}{\numberline {2.2.1}Query arguments}{4}{subsection.2.2.1}
\contentsline {subsection}{\numberline {2.3.1}Parsing of incoming content}{5}{subsection.2.3.1} \contentsline {subsection}{\numberline {2.2.2}Form encoded arguments}{5}{subsection.2.2.2}
\contentsline {subsection}{\numberline {2.3.2}Converting Python objects to expected content type}{5}{subsection.2.3.2} \contentsline {subsection}{\numberline {2.2.3}JSON document arguments}{5}{subsection.2.2.3}
\contentsline {section}{\numberline {2.4}Filters}{6}{section.2.4} \contentsline {subsection}{\numberline {2.2.4}YAML document arguments}{5}{subsection.2.2.4}
\contentsline {section}{\numberline {2.5}HTTP codes}{7}{section.2.5} \contentsline {subsection}{\numberline {2.2.5}XML document arguments}{5}{subsection.2.2.5}
\contentsline {section}{\numberline {2.6}Asynchronous Operations}{7}{section.2.6} \contentsline {section}{\numberline {2.3}Argument validation}{6}{section.2.3}
\contentsline {subsection}{\numberline {2.6.1}@defer.inlineCallbacks support}{7}{subsection.2.6.1} \contentsline {section}{\numberline {2.4}Content types}{6}{section.2.4}
\contentsline {section}{\numberline {2.7}Modular REST applications}{7}{section.2.7} \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}
Argument parsing
===================
CorePost can automatically parse query arguments, form arguments, as well as basic JSON, YAML and XML documents
and extract those as direct arguments to a REST router method.
Let's say we have a basic method that responds to GET, POST and PUT requests.
It expects a first name and last name and outputs them back in the response::
@router("/name",(Http.GET,Http.POST,Http.PUT))
def getName(self,request,first,last,**kwargs):
return "%s %s" % (first, last)
Query arguments
---------------
For GET requests, the query arguments will be automatically parsed, e.g.::
curl http://127.0.0.1/name?first=John&last=Doe
Form encoded arguments
----------------------
For POST/PUT requests, any form-encoded arguments will be automatically parsed, e.g.::
curl -X POST http://localhost/name -d "first=John&last=Doe"
JSON document arguments
-----------------------
For the same method, you could just post a JSON document instead that looks like this::
{"first":"John","last":"Doe"}
CorePost will automatically pass all the root elements of the document as arguments into a method.
Requires the *'application/json'* content type to be passed.
YAML document arguments
-----------------------
For the same method, you could just post a YAML document that looks like this::
first:John
last:Doe
CorePost will automatically pass all the root elements of the document as arguments into a method.
Requires the *'text/yaml'* content type to be passed.
XML document arguments
----------------------
XML documents are supported as well. In that case, CorePost will first parse all the attributes on the root node
and then all of the children underneath the main root node.
Hence all of the XML formats below are valid and would generate the same parameters to a method.
Attributes only::
<root first="John" last="Doe"/>
Mix of attributes and child nodes::
<root first="John">
<last>Doe</last>
</root>
Child nodes only::
<root>
<first>John</first>
<last>Doe</last>
</root>
Requires the *'text/xml'* OR *'application/xml'* content type to be passed.
As you can see from the examples above, a single CorePost router method can handle all these varied forms of argument parsing
for you without any additional effort.
...@@ -16,9 +16,11 @@ Features ...@@ -16,9 +16,11 @@ Features
:maxdepth: 4 :maxdepth: 4
url_routing url_routing
argument_parsing
arguments arguments
content_types content_types
filters filters
http_codes http_codes
async async
modules modules
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