• RESTful doctesting using app.request
  • !/usr/bin/env python

    RESTful doctesting using app.request

    !/usr/bin/env python

    1. """
    2. RESTful web.py testing
    3. usage: python webapp.py 8080 [--test]
    4. >>> req = app.request('/mathematicians', method='POST')
    5. >>> req.status
    6. '400 Bad Request'
    7. >>> name = {'first': 'Beno\xc3\xaet', 'last': 'Mandelbrot'}
    8. >>> data = urllib.urlencode(name)
    9. >>> req = app.request('/mathematicians', method='POST', data=data)
    10. >>> req.status
    11. '201 Created'
    12. >>> created_path = req.headers['Location']
    13. >>> created_path
    14. '/mathematicians/b-mandelbrot'
    15. >>> fn = '<h1 class=fn>{0} {1}</h1>'.format(name['first'], name['last'])
    16. >>> assert fn in app.request(created_path).data
    17. """
    18. import doctest
    19. import urllib
    20. import sys
    21. import web
    22. paths = (
    23. '/mathematicians(/)?', 'Mathematicians',
    24. '/mathematicians/([a-z])-([a-z]{2,})', 'Mathematician'
    25. )
    26. app = web.application(paths, globals())
    27. dbname = {True: 'test', False: 'production'}[sys.argv[-1] == '--test']
    28. db = {} # db = web.database(..., db='math_{0}'.format(dbname))
    29. class Mathematicians:
    30. def GET(self, slash=False):
    31. """list all mathematicians and form to create new one"""
    32. if slash:
    33. raise web.seeother('/mathematicians')
    34. mathematicians = db.items() # db.select(...)
    35. return web.template.Template("""$def with (mathematicians)
    36. <!doctype html>
    37. <html>
    38. <head>
    39. <meta charset=utf-8>
    40. <title>Mathematicians</title>
    41. </head>
    42. <body>
    43. <h1>Mathematicians</h1>
    44. $if mathematicians:
    45. <ul class=blogroll>
    46. $for path, name in mathematicians:
    47. <li class=vcard><a class="fn url"
    48. href=/mathematicians/$path>$name.first $name.last</a></li>
    49. </ul>
    50. <form action=/mathematicians method=post>
    51. <label>First <input name=first type=text></label>
    52. <label>Last <input name=last type=text></label>
    53. <input type=submit value=Add>
    54. </form>
    55. </body>
    56. </html>""")(mathematicians)
    57. def POST(self, _):
    58. """create new mathematician"""
    59. name = web.input('first', 'last')
    60. key = '{0}-{1}'.format(name.first[0].lower(), name.last.lower())
    61. name.first, name.last = name.first.capitalize(), name.last.capitalize()
    62. db[key] = name # db.insert(...)
    63. path = '/mathematicians/{0}'.format(key)
    64. web.ctx.status = '201 Created'
    65. web.header('Location', path)
    66. return web.template.Template("""$def with (path, name)
    67. <!doctype html>
    68. <html>
    69. <head>
    70. <meta charset=utf-8>
    71. <title>Profile Created</title>
    72. </head>
    73. <body>
    74. <p>Profile created for <a href=$path>$name.first $name.last</a>.</p>
    75. </body>
    76. </html>""")(path, name)
    77. class Mathematician:
    78. def GET(self, first_initial, last_name):
    79. """display mathematician"""
    80. key = '{0}-{1}'.format(first_initial, last_name)
    81. try:
    82. mathematician = db[key] # db.select(...)
    83. except KeyError:
    84. raise web.notfound()
    85. return web.template.Template("""$def with (name)
    86. <!doctype html>
    87. <html>
    88. <head>
    89. <meta charset=utf-8>
    90. <title>$name.first $name.last</title>
    91. </head>
    92. <body class=vcard>
    93. <p><a href=/mathematicians rel=up>Mathematicians</a> &#x25B8;</p>
    94. <h1 class=fn>$name.first $name.last</h1>
    95. </body>
    96. </html>""")(mathematician)
    97. if __name__ == "__main__":
    98. if sys.argv[-1] == '--test':
    99. doctest.testmod()
    100. else:
    101. app.run()