<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:"Lucida Console";
panose-1:2 11 6 9 4 5 4 2 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
span.EmailStyle17
{mso-style-type:personal;
font-family:"Calibri","sans-serif";
color:windowtext;}
span.EmailStyle18
{mso-style-type:personal-reply;
font-family:"Calibri","sans-serif";
color:#1F497D;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="color:#1F497D">Hi,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">We</span> have been struggling to get a decorator working for
<span style="color:#1F497D">proposed </span>new RBAC functionality in ceilometer-api. <span style="color:#1F497D">
</span>We’re hitting a problem where GET request query parameters are mucked up by our decorator. Here’s an example call:<span style="color:#1F497D"><o:p></o:p></span></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:"Lucida Console"">curl -H "X-Auth-Token:$TOKEN" '<a href="http://localhost:8777/v2/meters?q.field=project_id&q.value=8c678720fb5b4e3bb18dee222d7d7933'">http://localhost:8777/v2/meters?q.field=project_id&q.value=8c678720fb5b4e3bb18dee222d7d7933'</a></span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:"Lucida Console""> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:"Lucida Console"">And here’s the decorator method (we’ve tried changing the kwargs, args, etc. with no luck):</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:"Lucida Console""> </span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">_ENFORCER =
<span style="color:#00BFBF">None</span></span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:"Lucida Console""> </span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console";color:#BFBF00">def</span><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#00BFBF">protected</span>(controller_class):</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> </span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BFBF00">global</span> _ENFORCER</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BFBF00">if</span> <span style="color:#BFBF00">not</span> _ENFORCER:</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> _ENFORCER = policy.Enforcer()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> </span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BFBF00">def</span> <span style="color:#00BFBF">wrapper</span>(f):</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BF00BF">@</span><span style="color:#00BFBF">functools.wraps</span>(f)</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BFBF00">def</span> <span style="color:#00BFBF">inner</span>(self, **kwargs):</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> pdb.set_trace()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> self._rbac_context = {}</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BFBF00">if</span> <span style="color:#BFBF00">not</span> _ENFORCER.enforce(<span style="color:#BF0000">'context_is_admin'</span>,</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> {},</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> {<span style="color:#BF0000">'roles'</span>: pecan.request.headers.get(<span style="color:#BF0000">'X-Roles'</span>,
<span style="color:#BF0000">""</span>).split(<span style="color:#BF0000">","</span>)}):</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> self._rbac_context[<span style="color:#BF0000">'project_id'</span>] = pecan.request.headers.get(<span style="color:#BF0000">'X-Project-Id'</span>)</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> self._rbac_context[<span style="color:#BF0000">'user_id'</span>] = pecan.request.headers.get(<span style="color:#BF0000">'X-User-Id'</span>)</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BFBF00">return</span> f(self, **kwargs)</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BFBF00">return</span> inner</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BFBF00">return</span> wrapper</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:"Lucida Console""> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:"Lucida Console"">tried this too:</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:"Lucida Console""> </span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">_ENFORCER =
<span style="color:#00BFBF">None</span></span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console";color:#00BFBF"> </span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console";color:#BFBF00">def</span><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#00BFBF">protected</span>(*args):</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> </span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> controller_class =
<span style="color:#BF0000">'meter'</span></span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BFBF00">global</span> _ENFORCER</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BFBF00">if</span> <span style="color:#BFBF00">not</span> _ENFORCER:</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> _ENFORCER = policy.Enforcer()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> </span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BFBF00">def</span> <span style="color:#00BFBF">wrapper</span>(f, *args):</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BFBF00">def</span> <span style="color:#00BFBF">inner</span>(self, *args):</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> pdb.set_trace()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console";color:#0000BF"># self._rbac_context = {}</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console";color:#0000BF"># if not _ENFORCER.enforce('context_is_admin',</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console";color:#0000BF"># {},</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console";color:#0000BF"># {'roles': pecan.request.headers.get('X-Roles', "").split(",")}):</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console";color:#0000BF"># self._rbac_context['project_id'] = pecan.request.headers.get('X-Project-Id')</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console";color:#0000BF"># self._rbac_context['user_id'] = pecan.request.headers.get('X-User-Id')</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#0000BF">#return f(*args)</span></span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> f(self, *args)</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BFBF00">return</span> inner</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BFBF00">return</span> wrapper</span><o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">and here’s how it’s used:<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console";color:#BFBF00">class</span><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#00BFBF">MetersController</span>(rest.RestController):</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BF0000">"""Works on meters."""</span></span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console";color:#BF0000"> </span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> _rbac_context = {}</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BF00BF">@</span><span style="color:#00BFBF">pecan.expose</span>()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BFBF00">def</span> <span style="color:#00BFBF">_lookup</span>(self, meter_name, *remainder):</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BFBF00">return</span> MeterController(meter_name), remainder</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> </span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BF00BF">@</span><span style="color:#00BFBF">wsme_pecan.wsexpose</span>([Meter], [Query])</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console";color:#0000BF"> @rbac_validate.protected('meters')</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BFBF00">def</span> <span style="color:#00BFBF">get_all</span>(self, q=<span style="color:#00BFBF">None</span>):</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">
<span style="color:#BF0000">"""Return all known meters, based on the data recorded so far.</span></span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console";color:#BF0000"> </span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console";color:#BF0000"> :param q: Filter rules for the meters to be returned.</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console";color:#BF0000"> """</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> q = q
<span style="color:#BFBF00">or</span> [] …</span><o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">but we get errors similar to below where the arg parser cannot find the query parameter because the decorator doesn’t take a q argument as MetersController.get_all does.
<span style="color:#1F497D"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal">Is there any way to get a decorator to work within the v2 API code and wsme framework or should we consider another approach? Decorators would really simplify the RBAC idea we’re working on, which is mostly code-implemented save for this
fairly major problem.<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">I have a WIP registered BP on this at <a href="https://blueprints.launchpad.net/ceilometer/+spec/ready-ceilometer-rbac-keystone-v3">
https://blueprints.launchpad.net/ceilometer/+spec/ready-ceilometer-rbac-keystone-v3</a>.<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">If I can provide more details I’ll be happy to.<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">Thanks<o:p></o:p></p>
<p class="MsoNormal">Eric<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> /usr/local/bin/ceilometer-api(10)<module>()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> sys.exit(api())</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> /opt/stack/ceilometer/ceilometer/cli.py(96)api()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> srv.serve_forever()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> /usr/lib/python2.7/SocketServer.py(227)serve_forever()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> self._handle_request_noblock()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> /usr/lib/python2.7/SocketServer.py(284)_handle_request_noblock()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> self.process_request(request, client_address)</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> /usr/lib/python2.7/SocketServer.py(310)process_request()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> self.finish_request(request, client_address)</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> /usr/lib/python2.7/SocketServer.py(323)finish_request()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> self.RequestHandlerClass(request, client_address, self)</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> /usr/lib/python2.7/SocketServer.py(638)__init__()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> self.handle()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> /usr/lib/python2.7/wsgiref/simple_server.py(124)handle()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> handler.run(self.server.get_app())</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> /usr/lib/python2.7/wsgiref/handlers.py(85)run()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> self.result = application(self.environ, self.start_response)</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> /opt/stack/python-keystoneclient/keystoneclient/middleware/auth_token.py(663)__call__()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> return self.app(env, start_response)</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> /opt/stack/ceilometer/ceilometer/api/app.py(97)__call__()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> return self.v2(environ, start_response)</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> /usr/local/lib/python2.7/dist-packages/pecan/middleware/static.py(151)__call__()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> return self.app(environ, start_response)</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> /usr/local/lib/python2.7/dist-packages/pecan/middleware/debug.py(289)__call__()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> return self.app(environ, start_response)</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> /usr/local/lib/python2.7/dist-packages/pecan/middleware/recursive.py(56)__call__()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> return self.application(environ, start_response)</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> /opt/stack/ceilometer/ceilometer/api/middleware.py(83)__call__()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> app_iter = self.app(environ, replacement_start_response)</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> /usr/local/lib/python2.7/dist-packages/pecan/core.py(750)__call__()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> return super(Pecan, self).__call__(environ, start_response)</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> /usr/local/lib/python2.7/dist-packages/pecan/core.py(616)__call__()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> self.invoke_controller(controller, args, kwargs, state)</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> /usr/local/lib/python2.7/dist-packages/pecan/core.py(526)invoke_controller()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> result = controller(*args, **kwargs)</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> /usr/local/lib/python2.7/dist-packages/wsmeext/pecan.py(79)callfunction()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> pecan.request.body, pecan.request.content_type</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console""> /usr/local/lib/python2.7/dist-packages/wsme/rest/args.py(276)get_args()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> from_args = args_from_args(funcdef, args, kwargs)</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">> /usr/local/lib/python2.7/dist-packages/wsme/rest/args.py(189)args_from_args()</span><o:p></o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-size:9.0pt;font-family:"Lucida Console"">-> funcdef.get_arg(argname).datatype, value</span><o:p></o:p></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
</div>
</body>
</html>