Enhanced HttpError to now include the original request URI if possible.

This commit is contained in:
Joe Gregorio
2011-03-08 10:39:00 -05:00
parent afdf50bd1b
commit 493965528a
29 changed files with 226 additions and 82 deletions

View File

@@ -39,6 +39,7 @@ from anyjson import simplejson
from model import JsonModel
from errors import UnknownLinkType
from errors import HttpError
from errors import InvalidJsonError
URITEMPLATE = re.compile('{[^}]*}')
VARNAME = re.compile('[a-zA-Z0-9_-]+')
@@ -108,10 +109,12 @@ def build(serviceName, version,
requested_url = uritemplate.expand(discoveryServiceUrl, params)
logging.info('URL being requested: %s' % requested_url)
resp, content = http.request(requested_url)
if resp.status > 400:
raise HttpError(resp, content, requested_url)
try:
service = simplejson.loads(content)
except ValueError, e:
raise HttpError(resp, content)
raise InvalidJsonError()
fn = os.path.join(os.path.dirname(__file__), 'contrib',
serviceName, 'future.json')

View File

@@ -22,9 +22,10 @@ class Error(Exception):
class HttpError(Error):
"""HTTP data was invalid or unexpected."""
def __init__(self, resp, content):
def __init__(self, resp, content, uri=None):
self.resp = resp
self.content = content
self.uri = uri
def _get_reason(self):
"""Calculate the reason for the error from the response content.
@@ -40,11 +41,20 @@ class HttpError(Error):
return reason
def __repr__(self):
return '<HttpError %s "%s">' % (self.resp.status, self._get_reason())
if self.uri:
return '<HttpError %s when requesting %s returned "%s">' % (
self.resp.status, self.uri, self._get_reason())
else:
return '<HttpError %s "%s">' % (self.resp.status, self._get_reason())
__str__ = __repr__
class InvalidJsonError(Error):
"""The JSON returned could not be parsed."""
pass
class UnknownLinkType(Error):
"""Link type unknown or unexpected."""
pass

View File

@@ -16,6 +16,7 @@ import httplib2
import os
from model import JsonModel
from errors import HttpError
class HttpRequest(object):
@@ -67,6 +68,9 @@ class HttpRequest(object):
resp, content = http.request(self.uri, self.method,
body=self.body,
headers=self.headers)
if resp.status >= 300:
raise HttpError(resp, content, self.uri)
return self.postproc(resp, content)

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="apiclient.html"><font color="#ffffff">apiclient</font></a>.anyjson</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/apiclient/anyjson.py">/home/jcgregorio/projects/apiary/apiclient/anyjson.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/anyjson.py">/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/anyjson.py</a></font></td></tr></table>
<p><tt>Utility&nbsp;module&nbsp;to&nbsp;import&nbsp;a&nbsp;JSON&nbsp;module<br>
&nbsp;<br>
Hides&nbsp;all&nbsp;the&nbsp;messy&nbsp;details&nbsp;of&nbsp;exactly&nbsp;where<br>

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="apiclient.html"><font color="#ffffff">apiclient</font></a>.contrib</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/apiclient/contrib/__init__.py">/home/jcgregorio/projects/apiary/apiclient/contrib/__init__.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/contrib/__init__.py">/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/contrib/__init__.py</a></font></td></tr></table>
<p></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
@@ -17,6 +17,5 @@
<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="apiclient.contrib.buzz.html"><strong>buzz</strong>&nbsp;(package)</a><br>
</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table>
<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table>
</body></html>

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="apiclient.html"><font color="#ffffff">apiclient</font></a>.discovery</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/apiclient/discovery.py">/home/jcgregorio/projects/apiary/apiclient/discovery.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/discovery.py">/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/discovery.py</a></font></td></tr></table>
<p><tt>Client&nbsp;for&nbsp;discovery&nbsp;based&nbsp;APIs<br>
&nbsp;<br>
A&nbsp;client&nbsp;library&nbsp;for&nbsp;Google's&nbsp;discovery&nbsp;based&nbsp;APIs.</tt></p>

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="apiclient.html"><font color="#ffffff">apiclient</font></a>.errors</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/apiclient/errors.py">/home/jcgregorio/projects/apiary/apiclient/errors.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/errors.py">/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/errors.py</a></font></td></tr></table>
<p><tt>Errors&nbsp;for&nbsp;the&nbsp;library.<br>
&nbsp;<br>
All&nbsp;exceptions&nbsp;defined&nbsp;by&nbsp;the&nbsp;library<br>
@@ -36,6 +36,7 @@ should&nbsp;be&nbsp;defined&nbsp;in&nbsp;this&nbsp;file.</tt></p>
</font></dt><dd>
<dl>
<dt><font face="helvetica, arial"><a href="apiclient.errors.html#HttpError">HttpError</a>
</font></dt><dt><font face="helvetica, arial"><a href="apiclient.errors.html#InvalidJsonError">InvalidJsonError</a>
</font></dt><dt><font face="helvetica, arial"><a href="apiclient.errors.html#UnknownLinkType">UnknownLinkType</a>
</font></dt></dl>
</dd>
@@ -120,7 +121,7 @@ Data descriptors inherited from <a href="exceptions.html#BaseException">exceptio
</dl>
<hr>
Methods defined here:<br>
<dl><dt><a name="HttpError-__init__"><strong>__init__</strong></a>(self, resp, content)</dt></dl>
<dl><dt><a name="HttpError-__init__"><strong>__init__</strong></a>(self, resp, content, uri<font color="#909090">=None</font>)</dt></dl>
<dl><dt><a name="HttpError-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
@@ -155,6 +156,67 @@ Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd
<dl><dt><a name="HttpError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
<hr>
Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
<dl><dt><strong>__dict__</strong></dt>
</dl>
<dl><dt><strong>args</strong></dt>
</dl>
<dl><dt><strong>message</strong></dt>
</dl>
</td></tr></table> <p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ffc8d8">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#000000" face="helvetica, arial"><a name="InvalidJsonError">class <strong>InvalidJsonError</strong></a>(<a href="apiclient.errors.html#Error">Error</a>)</font></td></tr>
<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
<td colspan=2><tt>The&nbsp;JSON&nbsp;returned&nbsp;could&nbsp;not&nbsp;be&nbsp;parsed.<br>&nbsp;</tt></td></tr>
<tr><td>&nbsp;</td>
<td width="100%"><dl><dt>Method resolution order:</dt>
<dd><a href="apiclient.errors.html#InvalidJsonError">InvalidJsonError</a></dd>
<dd><a href="apiclient.errors.html#Error">Error</a></dd>
<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
</dl>
<hr>
Data descriptors inherited from <a href="apiclient.errors.html#Error">Error</a>:<br>
<dl><dt><strong>__weakref__</strong></dt>
<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
<hr>
Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
<dl><dt><a name="InvalidJsonError-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidJsonError-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;x.__class__.__doc__&nbsp;for&nbsp;signature</tt></dd></dl>
<hr>
Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#InvalidJsonError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
<hr>
Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
<dl><dt><a name="InvalidJsonError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidJsonError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
<dl><dt><a name="InvalidJsonError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidJsonError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
<dl><dt><a name="InvalidJsonError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidJsonError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
<dl><dt><a name="InvalidJsonError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidJsonError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
&nbsp;<br>
Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
<dl><dt><a name="InvalidJsonError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
<dl><dt><a name="InvalidJsonError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidJsonError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
<dl><dt><a name="InvalidJsonError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidJsonError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
<dl><dt><a name="InvalidJsonError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
<dl><dt><a name="InvalidJsonError-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidJsonError-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
<dl><dt><a name="InvalidJsonError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
<hr>
Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
<dl><dt><strong>__dict__</strong></dt>

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="apiclient.html"><font color="#ffffff">apiclient</font></a>.<a href="apiclient.ext.html"><font color="#ffffff">ext</font></a>.appengine</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/apiclient/ext/appengine.py">/home/jcgregorio/projects/apiary/apiclient/ext/appengine.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/ext/appengine.py">/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/ext/appengine.py</a></font></td></tr></table>
<p><tt>Utilities&nbsp;for&nbsp;Google&nbsp;App&nbsp;Engine<br>
&nbsp;<br>
Utilities&nbsp;for&nbsp;making&nbsp;it&nbsp;easier&nbsp;to&nbsp;use&nbsp;the<br>

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="apiclient.html"><font color="#ffffff">apiclient</font></a>.<a href="apiclient.ext.html"><font color="#ffffff">ext</font></a>.authtools</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/apiclient/ext/authtools.py">/home/jcgregorio/projects/apiary/apiclient/ext/authtools.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/ext/authtools.py">/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/ext/authtools.py</a></font></td></tr></table>
<p><tt>Command-line&nbsp;tools&nbsp;for&nbsp;authenticating&nbsp;via&nbsp;OAuth&nbsp;1.0<br>
&nbsp;<br>
Do&nbsp;the&nbsp;OAuth&nbsp;1.0&nbsp;Three&nbsp;Legged&nbsp;Dance&nbsp;for<br>

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="apiclient.html"><font color="#ffffff">apiclient</font></a>.<a href="apiclient.ext.html"><font color="#ffffff">ext</font></a>.django_orm</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/apiclient/ext/django_orm.py">/home/jcgregorio/projects/apiary/apiclient/ext/django_orm.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/ext/django_orm.py">/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/ext/django_orm.py</a></font></td></tr></table>
<p></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="apiclient.html"><font color="#ffffff">apiclient</font></a>.<a href="apiclient.ext.html"><font color="#ffffff">ext</font></a>.file</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/apiclient/ext/file.py">/home/jcgregorio/projects/apiary/apiclient/ext/file.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/ext/file.py">/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/ext/file.py</a></font></td></tr></table>
<p><tt>Utilities&nbsp;for&nbsp;OAuth.<br>
&nbsp;<br>
Utilities&nbsp;for&nbsp;making&nbsp;it&nbsp;easier&nbsp;to&nbsp;work&nbsp;with&nbsp;OAuth&nbsp;1.0&nbsp;credentials.</tt></p>

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="apiclient.html"><font color="#ffffff">apiclient</font></a>.ext</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/apiclient/ext/__init__.py">/home/jcgregorio/projects/apiary/apiclient/ext/__init__.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/ext/__init__.py">/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/ext/__init__.py</a></font></td></tr></table>
<p></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong>apiclient</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/apiclient/__init__.py">/home/jcgregorio/projects/apiary/apiclient/__init__.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/__init__.py">/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/__init__.py</a></font></td></tr></table>
<p></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
@@ -19,11 +19,12 @@
<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="apiclient.anyjson.html">anyjson</a><br>
<a href="apiclient.contrib.html"><strong>contrib</strong>&nbsp;(package)</a><br>
</td><td width="25%" valign=top><a href="apiclient.discovery.html">discovery</a><br>
<a href="apiclient.errors.html">errors</a><br>
</td><td width="25%" valign=top><a href="apiclient.ext.html"><strong>ext</strong>&nbsp;(package)</a><br>
<a href="apiclient.discovery.html">discovery</a><br>
</td><td width="25%" valign=top><a href="apiclient.errors.html">errors</a><br>
<a href="apiclient.ext.html"><strong>ext</strong>&nbsp;(package)</a><br>
<a href="apiclient.http.html">http</a><br>
</td><td width="25%" valign=top><a href="apiclient.model.html">model</a><br>
</td><td width="25%" valign=top><a href="apiclient.json.html">json</a><br>
<a href="apiclient.model.html">model</a><br>
<a href="apiclient.oauth.html">oauth</a><br>
</td></tr></table></td></tr></table>
</td><td width="25%" valign=top></td></tr></table></td></tr></table>
</body></html>

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="apiclient.html"><font color="#ffffff">apiclient</font></a>.http</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/apiclient/http.py">/home/jcgregorio/projects/apiary/apiclient/http.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/http.py">/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/http.py</a></font></td></tr></table>
<p><tt>Classes&nbsp;to&nbsp;encapsulate&nbsp;a&nbsp;single&nbsp;HTTP&nbsp;request.<br>
&nbsp;<br>
The&nbsp;classes&nbsp;implement&nbsp;a&nbsp;command&nbsp;pattern,&nbsp;with&nbsp;every<br>

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="apiclient.html"><font color="#ffffff">apiclient</font></a>.model</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/apiclient/model.py">/home/jcgregorio/projects/apiary/apiclient/model.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/model.py">/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/model.py</a></font></td></tr></table>
<p><tt><a href="#Model">Model</a>&nbsp;objects&nbsp;for&nbsp;requests&nbsp;and&nbsp;responses.<br>
&nbsp;<br>
Each&nbsp;API&nbsp;may&nbsp;support&nbsp;one&nbsp;or&nbsp;more&nbsp;serializations,&nbsp;such<br>
@@ -22,10 +22,11 @@ for&nbsp;converting&nbsp;between&nbsp;the&nbsp;wire&nbsp;format&nbsp;and&nbsp;th
<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="logging.html">logging</a><br>
<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="gflags.html">gflags</a><br>
</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
</td><td width="25%" valign=top><a href="simplejson.html">simplejson</a><br>
</td><td width="25%" valign=top><a href="urllib.html">urllib</a><br>
</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
</td></tr></table></td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ee77aa">
<td colspan=3 valign=bottom>&nbsp;<br>
@@ -40,10 +41,15 @@ for&nbsp;converting&nbsp;between&nbsp;the&nbsp;wire&nbsp;format&nbsp;and&nbsp;th
</font></dt><dd>
<dl>
<dt><font face="helvetica, arial"><a href="apiclient.model.html#JsonModel">JsonModel</a>
</font></dt><dd>
<dl>
<dt><font face="helvetica, arial"><a href="apiclient.model.html#LoggingJsonModel">LoggingJsonModel</a>
</font></dt></dl>
</dd>
</dl>
</dd>
</dl>
</dd>
</dl>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
@@ -97,6 +103,63 @@ Returns:<br>
Raises:<br>
&nbsp;&nbsp;apiclient.errors.HttpError&nbsp;if&nbsp;a&nbsp;non&nbsp;2xx&nbsp;response&nbsp;is&nbsp;received.</tt></dd></dl>
<hr>
Data descriptors inherited from <a href="apiclient.model.html#Model">Model</a>:<br>
<dl><dt><strong>__dict__</strong></dt>
<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
<dl><dt><strong>__weakref__</strong></dt>
<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
</td></tr></table> <p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ffc8d8">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#000000" face="helvetica, arial"><a name="LoggingJsonModel">class <strong>LoggingJsonModel</strong></a>(<a href="apiclient.model.html#JsonModel">JsonModel</a>)</font></td></tr>
<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
<td colspan=2><tt>A&nbsp;printable&nbsp;<a href="#JsonModel">JsonModel</a>&nbsp;class&nbsp;that&nbsp;supports&nbsp;logging&nbsp;response&nbsp;info.<br>&nbsp;</tt></td></tr>
<tr><td>&nbsp;</td>
<td width="100%"><dl><dt>Method resolution order:</dt>
<dd><a href="apiclient.model.html#LoggingJsonModel">LoggingJsonModel</a></dd>
<dd><a href="apiclient.model.html#JsonModel">JsonModel</a></dd>
<dd><a href="apiclient.model.html#Model">Model</a></dd>
<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
</dl>
<hr>
Methods defined here:<br>
<dl><dt><a name="LoggingJsonModel-request"><strong>request</strong></a>(self, headers, path_params, query_params, body_value)</dt><dd><tt>An&nbsp;overloaded&nbsp;request&nbsp;method&nbsp;that&nbsp;will&nbsp;output&nbsp;debug&nbsp;info&nbsp;if&nbsp;requested.<br>
&nbsp;<br>
Args:<br>
&nbsp;&nbsp;headers:&nbsp;dict,&nbsp;request&nbsp;headers<br>
&nbsp;&nbsp;path_params:&nbsp;dict,&nbsp;parameters&nbsp;that&nbsp;appear&nbsp;in&nbsp;the&nbsp;request&nbsp;path<br>
&nbsp;&nbsp;query_params:&nbsp;dict,&nbsp;parameters&nbsp;that&nbsp;appear&nbsp;in&nbsp;the&nbsp;query<br>
&nbsp;&nbsp;body_value:&nbsp;<a href="__builtin__.html#object">object</a>,&nbsp;the&nbsp;request&nbsp;body&nbsp;as&nbsp;a&nbsp;Python&nbsp;<a href="__builtin__.html#object">object</a>,&nbsp;which&nbsp;must&nbsp;be<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;serializable&nbsp;by&nbsp;simplejson.<br>
Returns:<br>
&nbsp;&nbsp;A&nbsp;tuple&nbsp;of&nbsp;(headers,&nbsp;path_params,&nbsp;query,&nbsp;body)<br>
&nbsp;<br>
&nbsp;&nbsp;headers:&nbsp;dict,&nbsp;request&nbsp;headers<br>
&nbsp;&nbsp;path_params:&nbsp;dict,&nbsp;parameters&nbsp;that&nbsp;appear&nbsp;in&nbsp;the&nbsp;request&nbsp;path<br>
&nbsp;&nbsp;query:&nbsp;string,&nbsp;query&nbsp;part&nbsp;of&nbsp;the&nbsp;request&nbsp;URI<br>
&nbsp;&nbsp;body:&nbsp;string,&nbsp;the&nbsp;body&nbsp;serialized&nbsp;as&nbsp;JSON</tt></dd></dl>
<dl><dt><a name="LoggingJsonModel-response"><strong>response</strong></a>(self, resp, content)</dt><dd><tt>An&nbsp;overloaded&nbsp;response&nbsp;method&nbsp;that&nbsp;will&nbsp;output&nbsp;debug&nbsp;info&nbsp;if&nbsp;requested.<br>
&nbsp;<br>
Args:<br>
&nbsp;&nbsp;resp:&nbsp;An&nbsp;httplib2.Response&nbsp;<a href="__builtin__.html#object">object</a>.<br>
&nbsp;&nbsp;content:&nbsp;A&nbsp;string&nbsp;representing&nbsp;the&nbsp;response&nbsp;body.<br>
&nbsp;<br>
Returns:<br>
&nbsp;&nbsp;The&nbsp;body&nbsp;de-serialized&nbsp;as&nbsp;a&nbsp;Python&nbsp;<a href="__builtin__.html#object">object</a>.</tt></dd></dl>
<hr>
Methods inherited from <a href="apiclient.model.html#JsonModel">JsonModel</a>:<br>
<dl><dt><a name="LoggingJsonModel-__init__"><strong>__init__</strong></a>(self, data_wrapper<font color="#909090">=False</font>)</dt><dd><tt>Construct&nbsp;a&nbsp;<a href="#JsonModel">JsonModel</a><br>
&nbsp;<br>
Args:<br>
&nbsp;&nbsp;data_wrapper:&nbsp;boolean,&nbsp;wrap&nbsp;requests&nbsp;and&nbsp;responses&nbsp;in&nbsp;a&nbsp;data&nbsp;wrapper</tt></dd></dl>
<hr>
Data descriptors inherited from <a href="apiclient.model.html#Model">Model</a>:<br>
<dl><dt><strong>__dict__</strong></dt>
@@ -162,7 +225,8 @@ Data descriptors defined here:<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><strong>__author__</strong> = 'jcgregorio@google.com (Joe Gregorio)'</td></tr></table><p>
<td width="100%"><strong>FLAGS</strong> = &lt;gflags.FlagValues instance&gt;<br>
<strong>__author__</strong> = 'jcgregorio@google.com (Joe Gregorio)'</td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#7799ee">
<td colspan=3 valign=bottom>&nbsp;<br>

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="apiclient.html"><font color="#ffffff">apiclient</font></a>.oauth</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/apiclient/oauth.py">/home/jcgregorio/projects/apiary/apiclient/oauth.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/oauth.py">/usr/local/google/home/jcgregorio/projects/apiclient/apiclient/oauth.py</a></font></td></tr></table>
<p><tt>Utilities&nbsp;for&nbsp;OAuth.<br>
&nbsp;<br>
Utilities&nbsp;for&nbsp;making&nbsp;it&nbsp;easier&nbsp;to&nbsp;work&nbsp;with&nbsp;OAuth.</tt></p>

View File

@@ -54,8 +54,9 @@ Args:<br>
&nbsp;&nbsp;useCase:&nbsp;string,&nbsp;One&nbsp;of&nbsp;CommerceSearchUseCase,&nbsp;ProductSearchUseCase<br>
&nbsp;&nbsp;debug_searchRequest:&nbsp;boolean,&nbsp;Google&nbsp;Internal<br>
&nbsp;&nbsp;facets_useGcsConfig:&nbsp;boolean,&nbsp;Whether&nbsp;to&nbsp;return&nbsp;facet&nbsp;information&nbsp;as&nbsp;configured&nbsp;in&nbsp;the&nbsp;GCS&nbsp;account<br>
&nbsp;&nbsp;boostBy:&nbsp;string,&nbsp;Boosting&nbsp;specification<br>
&nbsp;&nbsp;debug_enableLogging:&nbsp;boolean,&nbsp;Google&nbsp;Internal<br>
&nbsp;&nbsp;boostBy:&nbsp;string,&nbsp;Boosting&nbsp;specification<br>
&nbsp;&nbsp;safe:&nbsp;boolean,&nbsp;Whether&nbsp;safe&nbsp;search&nbsp;is&nbsp;enabled.&nbsp;Default:&nbsp;true<br>
&nbsp;&nbsp;maxResults:&nbsp;integer,&nbsp;Maximum&nbsp;number&nbsp;of&nbsp;results&nbsp;to&nbsp;return<br>
&nbsp;&nbsp;categories_enabled:&nbsp;boolean,&nbsp;Whether&nbsp;to&nbsp;return&nbsp;category&nbsp;information<br>
&nbsp;&nbsp;categories_useGcsConfig:&nbsp;boolean,&nbsp;This&nbsp;parameter&nbsp;is&nbsp;currently&nbsp;ignored<br>

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong>httplib2</strong></big></big> (version $Rev$)</font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/httplib2/__init__.py">/home/jcgregorio/projects/apiary/httplib2/__init__.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/httplib2/__init__.py">/usr/local/google/home/jcgregorio/projects/apiclient/httplib2/__init__.py</a></font></td></tr></table>
<p></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="httplib2.html"><font color="#ffffff">httplib2</font></a>.socks</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/httplib2/socks.py">/home/jcgregorio/projects/apiary/httplib2/socks.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/httplib2/socks.py">/usr/local/google/home/jcgregorio/projects/apiclient/httplib2/socks.py</a></font></td></tr></table>
<p><tt>SocksiPy&nbsp;-&nbsp;Python&nbsp;SOCKS&nbsp;module.<br>
Version&nbsp;1.00<br>
&nbsp;<br>

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="oauth2client.html"><font color="#ffffff">oauth2client</font></a>.appengine</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/oauth2client/appengine.py">/home/jcgregorio/projects/apiary/oauth2client/appengine.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/oauth2client/appengine.py">/usr/local/google/home/jcgregorio/projects/apiclient/oauth2client/appengine.py</a></font></td></tr></table>
<p><tt>Utilities&nbsp;for&nbsp;Google&nbsp;App&nbsp;Engine<br>
&nbsp;<br>
Utilities&nbsp;for&nbsp;making&nbsp;it&nbsp;easier&nbsp;to&nbsp;use&nbsp;OAuth&nbsp;2.0&nbsp;on&nbsp;Google&nbsp;App&nbsp;Engine.</tt></p>

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="oauth2client.html"><font color="#ffffff">oauth2client</font></a>.client</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/oauth2client/client.py">/home/jcgregorio/projects/apiary/oauth2client/client.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/oauth2client/client.py">/usr/local/google/home/jcgregorio/projects/apiclient/oauth2client/client.py</a></font></td></tr></table>
<p><tt>An&nbsp;OAuth&nbsp;2.0&nbsp;client<br>
&nbsp;<br>
Tools&nbsp;for&nbsp;interacting&nbsp;with&nbsp;OAuth&nbsp;2.0&nbsp;protected<br>

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="oauth2client.html"><font color="#ffffff">oauth2client</font></a>.django_orm</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/oauth2client/django_orm.py">/home/jcgregorio/projects/apiary/oauth2client/django_orm.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/oauth2client/django_orm.py">/usr/local/google/home/jcgregorio/projects/apiclient/oauth2client/django_orm.py</a></font></td></tr></table>
<p><tt>OAuth&nbsp;2.0&nbsp;utilities&nbsp;for&nbsp;Django.<br>
&nbsp;<br>
Utilities&nbsp;for&nbsp;using&nbsp;OAuth&nbsp;2.0&nbsp;in&nbsp;conjunction&nbsp;with<br>

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="oauth2client.html"><font color="#ffffff">oauth2client</font></a>.file</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/oauth2client/file.py">/home/jcgregorio/projects/apiary/oauth2client/file.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/oauth2client/file.py">/usr/local/google/home/jcgregorio/projects/apiclient/oauth2client/file.py</a></font></td></tr></table>
<p><tt>Utilities&nbsp;for&nbsp;OAuth.<br>
&nbsp;<br>
Utilities&nbsp;for&nbsp;making&nbsp;it&nbsp;easier&nbsp;to&nbsp;work&nbsp;with&nbsp;OAuth&nbsp;2.0<br>

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong>oauth2client</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/oauth2client/__init__.py">/home/jcgregorio/projects/apiary/oauth2client/__init__.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/oauth2client/__init__.py">/usr/local/google/home/jcgregorio/projects/apiclient/oauth2client/__init__.py</a></font></td></tr></table>
<p></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="oauth2client.html"><font color="#ffffff">oauth2client</font></a>.tools</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/oauth2client/tools.py">/home/jcgregorio/projects/apiary/oauth2client/tools.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/oauth2client/tools.py">/usr/local/google/home/jcgregorio/projects/apiclient/oauth2client/tools.py</a></font></td></tr></table>
<p><tt>Command-line&nbsp;tools&nbsp;for&nbsp;authenticating&nbsp;via&nbsp;OAuth&nbsp;2.0<br>
&nbsp;<br>
Do&nbsp;the&nbsp;OAuth&nbsp;2.0&nbsp;Web&nbsp;Server&nbsp;dance&nbsp;for&nbsp;a&nbsp;command&nbsp;line&nbsp;application.&nbsp;Stores&nbsp;the<br>

View File

@@ -8,7 +8,7 @@
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong>uritemplate</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/jcgregorio/projects/apiary/uritemplate/__init__.py">/home/jcgregorio/projects/apiary/uritemplate/__init__.py</a></font></td></tr></table>
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/usr/local/google/home/jcgregorio/projects/apiclient/uritemplate/__init__.py">/usr/local/google/home/jcgregorio/projects/apiclient/uritemplate/__init__.py</a></font></td></tr></table>
<p><tt>#&nbsp;Early,&nbsp;and&nbsp;incomplete&nbsp;implementation&nbsp;of&nbsp;-04.<br>
#</tt></p>
<p>

View File

@@ -21,18 +21,12 @@ from apiclient.model import LoggingJsonModel
FLAGS = gflags.FLAGS
FLAGS.dump_request_response = True
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def main(argv):
try:
argv = FLAGS(argv)
except gflags.FlagsError, e:
print '%s\\nUsage: %s ARGS\\n%s' % (e, argv[0], FLAGS)
sys.exit(1)
service = build('translate', 'v2',
developerKey='AIzaSyAQIKv_gwnob-YNrXV2stnY86GSGY81Zr0',
model=LoggingJsonModel())

View File

@@ -35,6 +35,7 @@ except ImportError:
from apiclient.discovery import build, key2param
from apiclient.http import HttpMock
from apiclient.errors import HttpError
from apiclient.errors import InvalidJsonError
DATA_DIR = os.path.join(os.path.dirname(__file__), 'data')
@@ -56,8 +57,8 @@ class DiscoveryErrors(unittest.TestCase):
try:
buzz = build('buzz', 'v1', self.http)
self.fail("should have raised an exception over malformed JSON.")
except HttpError, e:
self.assertEqual(e.content, "{\n")
except InvalidJsonError:
pass
class Discovery(unittest.TestCase):

View File

@@ -27,42 +27,7 @@ import httplib2
from apiclient.errors import HttpError
def fake_response(data, headers):
return httplib2.Response(headers), data
class Error(unittest.TestCase):
"""Test handling of error bodies."""
def test_json_body(self):
"""Test a nicely formed, expected error response."""
resp, content = fake_response(json_error_content,
{'status':'400', 'content-type': 'application/json'})
error = HttpError(resp, content)
self.assertEqual(str(error), '<HttpError 400 "country is required">')
def test_bad_json_body(self):
"""Test handling of bodies with invalid json."""
resp, content = fake_response('{',
{'status':'400', 'content-type': 'application/json'})
error = HttpError(resp, content)
self.assertEqual(str(error), '<HttpError 400 "{">')
def test_missing_message_json_body(self):
"""Test handling of bodies with missing expected 'message' element."""
resp, content = fake_response('{}',
{'status':'400', 'content-type': 'application/json'})
error = HttpError(resp, content)
self.assertEqual(str(error), '<HttpError 400 "{}">')
def test_non_json(self):
"""Test handling of non-JSON bodies"""
resp, content = fake_response('NOT OK', {'status':'400'})
error = HttpError(resp, content)
self.assertEqual(str(error), '<HttpError 400 "Ok">')
json_error_content = """
JSON_ERROR_CONTENT = """
{
"error": {
"errors": [
@@ -80,3 +45,43 @@ json_error_content = """
}
"""
def fake_response(data, headers):
return httplib2.Response(headers), data
class Error(unittest.TestCase):
"""Test handling of error bodies."""
def test_json_body(self):
"""Test a nicely formed, expected error response."""
resp, content = fake_response(JSON_ERROR_CONTENT,
{'status':'400', 'content-type': 'application/json'})
error = HttpError(resp, content)
self.assertEqual(str(error), '<HttpError 400 "country is required">')
def test_bad_json_body(self):
"""Test handling of bodies with invalid json."""
resp, content = fake_response('{',
{'status':'400', 'content-type': 'application/json'})
error = HttpError(resp, content)
self.assertEqual(str(error), '<HttpError 400 "{">')
def test_with_uri(self):
"""Test handling of passing in the request uri."""
resp, content = fake_response('{',
{'status':'400', 'content-type': 'application/json'})
error = HttpError(resp, content, 'http://example.org')
self.assertEqual(str(error), '<HttpError 400 when requesting http://example.org returned "{">')
def test_missing_message_json_body(self):
"""Test handling of bodies with missing expected 'message' element."""
resp, content = fake_response('{}',
{'status':'400', 'content-type': 'application/json'})
error = HttpError(resp, content)
self.assertEqual(str(error), '<HttpError 400 "{}">')
def test_non_json(self):
"""Test handling of non-JSON bodies"""
resp, content = fake_response('NOT OK', {'status':'400'})
error = HttpError(resp, content)
self.assertEqual(str(error), '<HttpError 400 "Ok">')