__main__.py 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import os
  2. import sys
  3. import signal
  4. import ipaddress
  5. import importlib
  6. import bjoern # Does not work for Windows
  7. from . import parser, utils
  8. DEFAULT_PORT: int = 8088
  9. def main():
  10. args = parser.parse_args()
  11. if args.workers < 1:
  12. raise AttributeError('Workers must not be less than 1')
  13. sys.path.insert(1, os.getcwd())
  14. full_module_path = args.positional[0]
  15. try:
  16. module_path, attr = full_module_path.split(':')
  17. except ValueError:
  18. raise AttributeError(
  19. f'No module attribute specified in "{full_module_path}"'
  20. )
  21. if not attr:
  22. raise AttributeError(
  23. f'Module attribute cannot be empty ({full_module_path})')
  24. module = importlib.import_module(module_path)
  25. app = getattr(module, attr)
  26. workers = args.workers
  27. host = args.host
  28. port = args.port
  29. if not port:
  30. try:
  31. ipaddress.ip_network(host)
  32. port = DEFAULT_PORT
  33. except ValueError:
  34. pass
  35. print(f'Starting Bjoern on {host}{f":{port}" if port else ""}')
  36. bjoern.listen(app, host, port)
  37. print('Bjoern server has started')
  38. if not port:
  39. utils.set_socket_permissions(host)
  40. pids = utils.create_workers(workers)
  41. if not pids:
  42. try:
  43. bjoern.run()
  44. except FileNotFoundError as e:
  45. print(e)
  46. except KeyboardInterrupt:
  47. pass
  48. sys.exit()
  49. try:
  50. # Wait for the first worker to exit. They should never exit!
  51. # Once first is dead, kill the others and exit with error code.
  52. pid, _ = os.wait()
  53. pids.remove(pid)
  54. finally:
  55. for pid in pids:
  56. os.kill(pid, signal.SIGINT)
  57. sys.exit(1)
  58. if __name__ == '__main__':
  59. main()