ProjectManager.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. from glob import glob
  2. from json import load, dump
  3. from os import path, mkdir
  4. from shutil import rmtree, copytree
  5. from time import time
  6. from uuid import uuid1
  7. from eventlet import spawn_after
  8. from pycs import ApplicationStatus
  9. from pycs.observable import ObservableDict
  10. from pycs.pipeline.PipelineManager import PipelineManager
  11. from pycs.projects.Project import Project
  12. class ProjectManager(ObservableDict):
  13. DEFAULT_PIPELINE_TIMEOUT = 120
  14. def __init__(self, app_status: ApplicationStatus):
  15. self.pipeline_manager = None
  16. self.quit_pipeline_thread = None
  17. # TODO create projects folder if it does not exist
  18. self.app_status = app_status
  19. # initialize observable dict with no keys and
  20. # app_status object as parent
  21. super().__init__({}, app_status)
  22. app_status['projects'] = self
  23. # find projects
  24. for folder in glob('projects/*'):
  25. # load project.json
  26. with open(path.join(folder, 'project.json'), 'r') as file:
  27. project = Project(load(file), self)
  28. self[project['id']] = project
  29. def write_project(self, uuid):
  30. with open(path.join('projects', uuid, 'project.json'), 'w') as file:
  31. copy = self[uuid].copy()
  32. del copy['jobs']
  33. del copy['model']
  34. dump(copy, file, indent=4)
  35. def create_project(self, name, description, model):
  36. # create dict representation
  37. uuid = str(uuid1())
  38. # create project directory
  39. folder = path.join('projects', uuid)
  40. mkdir(folder)
  41. # copy model to project directory
  42. copytree(self.parent['models'][model]['path'], path.join(folder, 'model'))
  43. # create project object
  44. self[uuid] = Project({
  45. 'id': uuid,
  46. 'name': name,
  47. 'description': description,
  48. 'created': int(time()),
  49. 'data': {},
  50. 'labels': {},
  51. 'jobs': {}
  52. }, self)
  53. # create project.json
  54. self.write_project(uuid)
  55. def update_project(self, uuid, update):
  56. # abort if uuid is no valid key
  57. if uuid not in self.keys():
  58. return
  59. # set values and write to disk
  60. self[uuid].update_properties(update)
  61. self.write_project(uuid)
  62. def delete_project(self, uuid):
  63. # abort if uuid is no valid key
  64. if uuid not in self.keys():
  65. return
  66. # delete project folder
  67. folder = path.join('projects', uuid)
  68. rmtree(folder)
  69. # delete project data
  70. del self[uuid]
  71. def predict(self, uuid, identifiers):
  72. # abort if uuid is no valid key
  73. if uuid not in self.keys():
  74. return
  75. project = self[uuid]
  76. # abort pipeline termination
  77. if self.quit_pipeline_thread is not None:
  78. self.quit_pipeline_thread.cancel()
  79. self.quit_pipeline_thread = None
  80. # create pipeline if it does not exist already
  81. if self.pipeline_manager is None:
  82. # abort if pipeline id is no valid key
  83. pipeline_identifier = project['pipeline']['model-distribution']
  84. pipeline = self.parent['models'][pipeline_identifier]
  85. self.pipeline_manager = PipelineManager(project, pipeline)
  86. # run jobs
  87. for file_id in identifiers:
  88. if file_id in project['data'].keys():
  89. self.pipeline_manager.run(project['data'][file_id])
  90. # quit timeout thread
  91. if self.quit_pipeline_thread is not None:
  92. self.quit_pipeline_thread.cancel()
  93. self.quit_pipeline_thread = None
  94. # schedule timeout thread
  95. self.quit_pipeline_thread = spawn_after(self.DEFAULT_PIPELINE_TIMEOUT, self.__quit_pipeline)
  96. def __quit_pipeline(self):
  97. if self.pipeline_manager is not None:
  98. self.pipeline_manager.close()
  99. self.pipeline_manager = None
  100. self.quit_pipeline_thread = None