You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
5.0 KiB

3 years ago
2 years ago
2 years ago
3 years ago
2 years ago
2 years ago
3 years ago
2 years ago
3 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. import argparse
  2. import multiprocessing
  3. import os
  4. import platform
  5. import sys
  6. from pathlib import Path
  7. import django
  8. from django.core import management
  9. from .config.celery import app
  10. DOCCANO_HOME = os.path.expanduser(os.environ.get("DOCCANO_HOME", "~/doccano"))
  11. Path(DOCCANO_HOME).mkdir(parents=True, exist_ok=True)
  12. os.environ["STANDALONE"] = "True"
  13. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.production")
  14. os.environ.setdefault("DATABASE_URL", os.path.join(f"sqlite:///{DOCCANO_HOME}", "db.sqlite3"))
  15. os.environ.setdefault("MEDIA_ROOT", os.path.join(DOCCANO_HOME, "media"))
  16. base = os.path.abspath(os.path.dirname(__file__))
  17. sys.path.append(base)
  18. django.setup()
  19. parser = argparse.ArgumentParser(description="doccano, text annotation for machine learning practitioners.")
  20. def number_of_workers():
  21. return (multiprocessing.cpu_count() * 2) + 1
  22. def is_windows():
  23. return platform.system() == "Windows"
  24. def run_on_nix(args):
  25. import gunicorn.app.base
  26. import gunicorn.util
  27. class StandaloneApplication(gunicorn.app.base.BaseApplication):
  28. def __init__(self, options=None):
  29. self.options = options or {}
  30. super().__init__()
  31. def load_config(self):
  32. config = {
  33. key: value for key, value in self.options.items() if key in self.cfg.settings and value is not None
  34. }
  35. for key, value in config.items():
  36. self.cfg.set(key.lower(), value)
  37. def load(self):
  38. return gunicorn.util.import_app("config.wsgi")
  39. options = {
  40. "bind": "%s:%s" % ("0.0.0.0", args.port),
  41. "workers": args.workers,
  42. "chdir": base,
  43. "capture_output": True,
  44. "loglevel": "debug",
  45. }
  46. StandaloneApplication(options).run()
  47. def run_on_windows(args):
  48. from waitress import serve
  49. from config.wsgi import application
  50. serve(application, port=args.port)
  51. def command_db_init(args):
  52. print("Setup Database.")
  53. management.call_command("wait_for_db")
  54. management.call_command("migrate")
  55. management.call_command("create_roles")
  56. def command_user_create(args):
  57. print("Create admin user.")
  58. management.call_command(
  59. "create_admin", "--noinput", username=args.username, password=args.password, email=args.email
  60. )
  61. def command_migrate(args):
  62. print("Start migration.")
  63. management.call_command("migrate")
  64. def command_run_webserver(args):
  65. print(f"Starting server with port {args.port}.")
  66. if is_windows():
  67. run_on_windows(args)
  68. else:
  69. run_on_nix(args)
  70. def command_run_task_queue(args):
  71. print("Starting task queue.")
  72. argv = [
  73. "--app=config",
  74. "--workdir={}".format(base),
  75. "worker",
  76. "--loglevel=info",
  77. "--concurrency={}".format(args.concurrency),
  78. ]
  79. if is_windows():
  80. argv.append("--pool=solo")
  81. app.worker_main(argv=argv)
  82. def command_help(args):
  83. print(parser.parse_args([args.command, "--help"]))
  84. def main():
  85. # Create a command line parser.
  86. subparsers = parser.add_subparsers()
  87. # Create a parser for db initialization.
  88. parser_init = subparsers.add_parser("init", help="see `init -h`")
  89. parser_init.set_defaults(handler=command_db_init)
  90. # Create a parser for migration.
  91. parser_migration = subparsers.add_parser("migrate", help="Updates database schema.")
  92. parser_migration.set_defaults(handler=command_migrate)
  93. # Create a parser for user creation.
  94. parser_create_user = subparsers.add_parser("createuser", help="see `createuser -h`")
  95. parser_create_user.add_argument("--username", type=str, default="admin", help="admin username")
  96. parser_create_user.add_argument("--password", type=str, default="password", help="admin password")
  97. parser_create_user.add_argument("--email", type=str, default="example@example.com", help="admin email")
  98. parser_create_user.set_defaults(handler=command_user_create)
  99. # Create a parser for web server.
  100. parser_server = subparsers.add_parser("webserver", help="see `webserver -h`")
  101. parser_server.add_argument("--port", type=int, default=8000, help="port number")
  102. parser_server.add_argument("--workers", type=int, default=number_of_workers(), help="the number of workers")
  103. parser_server.set_defaults(handler=command_run_webserver)
  104. # Create a parser for task queue.
  105. parser_queue = subparsers.add_parser("task", help="see `task -h`")
  106. parser_queue.add_argument("--concurrency", type=int, default=2, help="concurrency")
  107. parser_queue.set_defaults(handler=command_run_task_queue)
  108. # Create a parser for help.
  109. parser_help = subparsers.add_parser("help", help="see `help -h`")
  110. parser_help.add_argument("command", help="command name which help is shown")
  111. parser_help.set_defaults(handler=command_help)
  112. # Dispatch handler.
  113. args = parser.parse_args()
  114. if hasattr(args, "handler"):
  115. args.handler(args)
  116. else:
  117. # If specified unknown command, show help.
  118. parser.print_help()
  119. if __name__ == "__main__":
  120. main()