app_bjoern.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #!/usr/bin/env python
  2. import bjoern
  3. import falcon
  4. import re
  5. from email.utils import formatdate
  6. from db_orm import session, World, Fortune
  7. from helpers import load_template, FortuneTuple, generate_ids, sanitize
  8. from operator import attrgetter
  9. from random import randint
  10. # setup
  11. wsgi = app = falcon.App()
  12. # Note:
  13. # Bjoern doesn't provide any additional response headers like Date and Server
  14. # so we need to provide them manually.
  15. bjoern_version = [i for i in open('requirements-bjoern.txt', 'r') if re.search('bjoern', i)][0].strip().split('==')
  16. server_info = '{}/{}'.format(*bjoern_version).title()
  17. # resource endpoints
  18. class JSONResource(object):
  19. def on_get(self, request, response):
  20. response.set_header('Date', formatdate(timeval=None, localtime=False, usegmt=True))
  21. response.set_header('Server', server_info)
  22. response.media = {'message': "Hello, world!"}
  23. class SingleQuery(object):
  24. @session(serializable=False)
  25. def on_get(self, request, response):
  26. wid = randint(1, 10000)
  27. world = World[wid]
  28. response.set_header('Date', formatdate(timeval=None, localtime=False, usegmt=True))
  29. response.set_header('Server', server_info)
  30. response.media = world.to_dict()
  31. class MultipleQueries(object):
  32. @session(serializable=False)
  33. def on_get(self, request, response, num):
  34. num = sanitize(num)
  35. worlds = [World[ident].to_dict() for ident in generate_ids(num)]
  36. response.set_header('Date', formatdate(timeval=None, localtime=False, usegmt=True))
  37. response.set_header('Server', server_info)
  38. response.media = worlds
  39. class UpdateQueries(object):
  40. @session(serializable=False)
  41. def on_get(self, request, response, num):
  42. num = sanitize(num)
  43. ids = generate_ids(num)
  44. ids.sort()
  45. worlds = []
  46. for item in ids:
  47. world = World[item]
  48. world.randomNumber = randint(1, 10000)
  49. worlds.append({"id": world.id, "randomNumber": world.randomNumber})
  50. response.set_header('Date', formatdate(timeval=None, localtime=False, usegmt=True))
  51. response.set_header('Server', server_info)
  52. response.media = worlds
  53. class Fortunes(object):
  54. _template = load_template()
  55. @session(serializable=False)
  56. def on_get(self, request, response):
  57. fortunes = [FortuneTuple(id=f.id, message=f.message) for f in Fortune.select()]
  58. fortunes.append(FortuneTuple(id=0, message="Additional fortune added at request time."))
  59. fortunes.sort(key=attrgetter("message"))
  60. content = self._template.render(fortunes=fortunes)
  61. response.set_header('Date', formatdate(timeval=None, localtime=False, usegmt=True))
  62. response.set_header('Server', server_info)
  63. response.content_type = falcon.MEDIA_HTML
  64. response.text = content
  65. class PlaintextResource(object):
  66. def on_get(self, request, response):
  67. response.set_header('Date', formatdate(timeval=None, localtime=False, usegmt=True))
  68. response.set_header('Server', server_info)
  69. response.content_type = falcon.MEDIA_TEXT
  70. response.text = 'Hello, world!'
  71. # register resources
  72. app.add_route("/json", JSONResource())
  73. app.add_route("/db", SingleQuery())
  74. app.add_route("/queries/{num}", MultipleQueries())
  75. app.add_route("/updates/{num}", UpdateQueries())
  76. app.add_route("/fortunes", Fortunes())
  77. app.add_route("/plaintext", PlaintextResource())
  78. if __name__ == "__main__":
  79. import os
  80. import multiprocessing
  81. _is_travis = os.environ.get('TRAVIS') == 'true'
  82. workers = int(multiprocessing.cpu_count())
  83. if _is_travis:
  84. workers = 2
  85. host = '0.0.0.0'
  86. port = 8080
  87. def run_app():
  88. bjoern.run(wsgi, host=host, port=port, reuse_port=True)
  89. def create_fork():
  90. n = os.fork()
  91. # n greater than 0 means parent process
  92. if not n > 0:
  93. run_app()
  94. # fork limiting the cpu count - 1
  95. for i in range(1, workers):
  96. create_fork()
  97. run_app() # run app on the main process too :)