Model.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import json
  2. from pathlib import Path
  3. from pycs import db
  4. from pycs.database.base import NamedBaseModel
  5. from pycs.database.util import commit_on_return
  6. class Model(NamedBaseModel):
  7. """
  8. DB model for ML models
  9. """
  10. description = db.Column(db.String)
  11. root_folder = db.Column(db.String, nullable=False, unique=True)
  12. supports_encoded = db.Column(db.String, nullable=False)
  13. # relationships to other models
  14. projects = db.relationship("Project", backref="model", lazy="dynamic")
  15. serialize_only = NamedBaseModel.serialize_only + (
  16. "description",
  17. "root_folder",
  18. )
  19. def serialize(self):
  20. result = super().serialize()
  21. result["supports"] = self.supports
  22. return result
  23. @classmethod
  24. def discover(cls, root: Path, config_name: str = "configuration.json"):
  25. """
  26. searches for models under the given path
  27. and stores them in the database
  28. """
  29. for folder in Path(root).glob("*"):
  30. with open(folder / config_name) as config_file:
  31. config = json.load(config_file)
  32. # extract data
  33. name = config['name']
  34. description = config.get('description', None)
  35. supports = config['supports']
  36. model, _ = cls.get_or_create(root_folder=str(folder))
  37. model.name = name
  38. model.description = description
  39. model.supports = supports
  40. model.flush()
  41. db.session.commit()
  42. @property
  43. def supports(self) -> dict:
  44. """ getter for the 'supports' attribute """
  45. return json.loads(self.supports_encoded)
  46. @supports.setter
  47. def supports(self, value):
  48. """
  49. setter for the 'supports' attribute.
  50. The attribute is encoded property before assigned to the object.
  51. """
  52. if isinstance(value, str):
  53. self.supports_encoded = value
  54. elif isinstance(value, (dict, list)):
  55. self.supports_encoded = json.dumps(value)
  56. else:
  57. raise ValueError(f"Not supported type: {type(value)}")
  58. @commit_on_return
  59. def copy_to(self, name: str, root_folder: str):
  60. """ copies current model to another folder and updates the name """
  61. model, is_new = Model.get_or_create(root_folder=root_folder)
  62. model.name = name
  63. model.description = self.description
  64. model.supports_encoded = self.supports_encoded
  65. return model, is_new