serve_bottle.py 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. # -*- coding: utf-8 -*-
  2. import bottle
  3. from datetime import datetime
  4. try: # Python 3.5+
  5. from http import HTTPStatus
  6. except ImportError:
  7. from http import client as HTTPStatus
  8. import json
  9. import time
  10. from hapic import Hapic
  11. from hapic.data import HapicData
  12. from hapic.ext.bottle import BottleContext
  13. from example.usermanagement.schema import AboutSchema
  14. from example.usermanagement.schema import NoContentSchema
  15. from example.usermanagement.schema import UserDigestSchema
  16. from example.usermanagement.schema import UserIdPathSchema
  17. from example.usermanagement.schema import UserSchema
  18. from example.usermanagement.userlib import User
  19. from example.usermanagement.userlib import UserLib
  20. from example.usermanagement.userlib import UserNotFound
  21. hapic = Hapic()
  22. class BottleController(object):
  23. @hapic.with_api_doc()
  24. @hapic.output_body(AboutSchema())
  25. def about(self, context, request):
  26. """
  27. This endpoint allow to check that the API is running. This description
  28. is generated from the docstring of the method.
  29. """
  30. return {
  31. 'version': '1.2.3',
  32. 'datetime': datetime.now(),
  33. }
  34. @hapic.with_api_doc()
  35. @hapic.output_body(UserDigestSchema(many=True))
  36. def get_users(self):
  37. """
  38. Obtain users list.
  39. """
  40. return UserLib().get_users()
  41. @hapic.with_api_doc()
  42. @hapic.handle_exception(UserNotFound, HTTPStatus.NOT_FOUND)
  43. @hapic.input_path(UserIdPathSchema())
  44. @hapic.output_body(UserSchema())
  45. def get_user(self, id, hapic_data: HapicData):
  46. """
  47. Return a user taken from the list or return a 404
  48. """
  49. return UserLib().get_user(int(hapic_data.path['id']))
  50. @hapic.with_api_doc()
  51. # TODO - G.M - 2017-12-5 - Support input_forms ?
  52. # TODO - G.M - 2017-12-5 - Support exclude, only ?
  53. @hapic.input_body(UserSchema(exclude=('id',)))
  54. @hapic.output_body(UserSchema())
  55. def add_user(self, hapic_data: HapicData):
  56. """
  57. Add a user to the list
  58. """
  59. print(hapic_data.body)
  60. new_user = User(**hapic_data.body)
  61. return UserLib().add_user(new_user)
  62. @hapic.with_api_doc()
  63. @hapic.handle_exception(UserNotFound, HTTPStatus.NOT_FOUND)
  64. @hapic.output_body(NoContentSchema(), default_http_code=204)
  65. @hapic.input_path(UserIdPathSchema())
  66. def del_user(self, id, hapic_data: HapicData):
  67. UserLib().del_user(int(hapic_data.path['id']))
  68. return NoContentSchema()
  69. def bind(self, app:bottle.Bottle):
  70. app.route('/about', callback=self.about)
  71. app.route('/users', callback=self.get_users)
  72. app.route('/users/<id>', callback=self.get_user)
  73. app.route('/users', callback=self.add_user, method='POST')
  74. app.route('/users/<id>', callback=self.del_user, method='DELETE')
  75. if __name__ == "__main__":
  76. app = bottle.Bottle()
  77. controllers = BottleController()
  78. controllers.bind(app)
  79. hapic.set_context(BottleContext(app))
  80. print('')
  81. print('')
  82. print('GENERATING OPENAPI DOCUMENTATION')
  83. openapi_file_name = 'api-documentation.json'
  84. with open(openapi_file_name, 'w') as openapi_file_handle:
  85. openapi_file_handle.write(
  86. json.dumps(
  87. hapic.generate_doc(
  88. title='Demo API documentation',
  89. description='This documentation has been generated from '
  90. 'code. You can see it using swagger: '
  91. 'http://editor2.swagger.io/'
  92. )
  93. )
  94. )
  95. print('Documentation generated in {}'.format(openapi_file_name))
  96. time.sleep(1)
  97. print('')
  98. print('')
  99. print('RUNNING BOTTLE SERVER NOW')
  100. # Run app
  101. app.run(host='127.0.0.1', port=8081, debug=True)