class IntegrationReply(ReplyValue): value = Attribute( MappingType( 'type', { PLAIN_TYPE: ObjectType(PlainType), INTEGRATION_TYPE: ObjectType(IntegrationType), }))
class QuestionnaireReportDTO(AttributesMixin): indications = ListAttribute( MappingType( 'indication_type', { ANSWERED_INDICATION: ObjectType(AnsweredIndication), LEVELS_ANSWERED_INDICATION: ObjectType(LevelsAnsweredIndication), }))
class QuestionnairePermRecordDTO(AttributesMixin): member = Attribute( MappingType( 'type', { GROUP_MEMBER: ObjectType(GroupMember), USER_MEMBER: ObjectType(UserMember), })) perms = ListAttribute(StringType())
class SetReplyEvent(QuestionnaireEvent): path = StringAttribute(nullable=True) value = Attribute(MappingType( 'type', { ANSWER_REPLY: ObjectType(AnswerReply), INTEGRATION_REPLY: ObjectType(IntegrationReply), ITEM_LIST_REPLY: ObjectType(ItemListReply), MULTI_CHOICE_REPLY: ObjectType(MultiChoiceReply), STRING_REPLY: ObjectType(StringReply), }), nullable=True)
class Reply(AttributesMixin): created_at = DateTimeAttribute() created_by = ObjectAttribute(UserSuggestion) value = Attribute( MappingType( 'type', { ANSWER_REPLY: ObjectType(AnswerReply), INTEGRATION_REPLY: ObjectType(IntegrationReply), ITEM_LIST_REPLY: ObjectType(ItemListReply), MULTI_CHOICE_REPLY: ObjectType(MultiChoiceReply), STRING_REPLY: ObjectType(StringReply), }))
class QuestionnaireDTO(AttributesMixin): created_at = DateTimeAttribute() level = IntegerAttribute() name = StringAttribute() package = ObjectAttribute(PackageSimpleDTO) permissions = ListAttribute(ObjectType(QuestionnairePermRecordDTO)) report = ObjectType(QuestionnaireReportDTO) sharing = StringAttribute(choices=QUESTIONNAIRE_SHARING) state = StringAttribute(choices=QUESTIONNAIRE_STATES) updated_at = DateTimeAttribute() uuid = StringAttribute() visibility = StringAttribute(choices=QUESTIONNAIRE_VISIBILITIES)
class TemplateChangeDTO(AttributesMixin): allowed_packages = ListAttribute(ObjectType(TemplateAllowedPackage)) description = StringAttribute() formats = ListAttribute(ObjectType(TemplateFormat)) license = StringAttribute() metamodel_version = IntegerAttribute() name = StringAttribute() organization_id = StringAttribute() readme = StringAttribute() recommended_package_id = StringAttribute(nullable=True) template_id = StringAttribute() version = StringAttribute()
class TemplateSimpleDTO(TemplateSimple): allowed_packages = ListAttribute(ObjectType(TemplateAllowedPackage)) created_at = DateTimeAttribute(read_only=True) license = StringAttribute() metamodel_version = IntegerAttribute() organization = ObjectAttribute(OrganizationSimple, nullable=True, read_only=True) organization_id = StringAttribute() readme = StringAttribute() recommended_package_id = StringAttribute(nullable=True) state = StringAttribute(choices=TEMPLATE_STATES, read_only=True) template_id = StringAttribute() usable_packages = ListAttribute(ObjectType(PackageSimpleDTO), read_only=True)
class AppConfigLookAndFeel(AttributesMixin): app_title = StringAttribute(nullable=True) app_title_short = StringAttribute(nullable=True) custom_menu_links = ListAttribute( ObjectType(AppConfigLookAndFeelCustomMenuLink) ) login_info = StringAttribute(nullable=True)
class TemplateFormat(AttributesMixin): color = StringAttribute() icon = StringAttribute() name = StringAttribute() short_name = StringAttribute() steps = ListAttribute(ObjectType(TemplateFormatStep), nullable=True) uuid = StringAttribute()
class AppConfigSubmissionService(AttributesMixin): description = StringAttribute() id = StringAttribute() name = StringAttribute() props = ListAttribute(StringType()) request = ObjectAttribute(AppConfigSubmissionServiceRequest) supported_formats = ListAttribute( ObjectType(AppConfigSubmissionServiceSupportedFormat) )
class AppConfigAuthExternalService(AttributesMixin): client_id = StringAttribute() client_secret = StringAttribute() id = StringAttribute() name = StringAttribute() parameteres = ListAttribute( ObjectType(AppConfigAuthExternalServiceParameter) ) style = ObjectAttribute(AppConfigAuthExternalServiceStyle, nullable=True) url = StringAttribute()
class User(Model): _eq_ignore = ['password'] active: bool = BoolAttribute() affiliation: str = StringAttribute(nullable=True) created_at: datetime = DateTimeAttribute(nullable=True, read_only=True) email: str = StringAttribute() first_name: str = StringAttribute() groups: List[GroupMembership] = ListAttribute(ObjectType(GroupMembership), read_only=True) image_url: str = StringAttribute(nullable=True, read_only=True) last_name: str = StringAttribute() password: str = StringAttribute() permissions: List[str] = ListAttribute(StringType(), read_only=True) role: str = StringAttribute() sources: List[str] = ListAttribute(StringType(), read_only=True) updated_at: datetime = DateTimeAttribute(nullable=True, read_only=True) questionnaires = ListOfModelsAttribute(Questionnaire, default=[], read_only=True) def _create(self): dto = UserCreateDTO(**self.attrs()) dto.validate() data = self._sdk.api.post_users(body=dto.to_json()).json() self._update_attrs(**data) def _update(self): diff = snapshots_diff(self._snapshot, make_snapshot(self)) if 'password' in diff: body = {'password': self.password} self._sdk.api.put_user_password(self.uuid, body=body) if len(diff) > 1 or 'password' not in diff: dto = UserChangeDTO(**self.attrs()) dto.validate() data = self._sdk.api.put_user(self.uuid, body=dto.to_json()).json() self._update_attrs(**data) def _delete(self): self._sdk.api.delete_user(self.uuid)
class Questionnaire(Model): created_at = DateTimeAttribute() creator_uuid = StringAttribute(nullable=True) events = ListAttribute(MappingType('type', { SET_REPLY_EVENT: ObjectType(SetReplyEvent), CLEAR_REPLY_EVENT: ObjectType(ClearReplyEvent), SET_LEVEL_EVENT: ObjectType(SetLevelEvent), SET_LABELS_EVENT: ObjectType(SetLabelsEvent), })) format = ObjectAttribute(TemplateFormat, nullable=True) format_uuid = StringAttribute(nullable=True) knowledge_model = ObjectAttribute(KnowledgeModel) labels = DictAttribute(StringType(), StringType()) level = IntegerAttribute() name = StringAttribute() package = ObjectAttribute(PackageSimpleDTO) permissions = ListAttribute(ObjectType(QuestionnairePermRecordDTO)) replies = DictAttribute(StringType(), ObjectType(Reply)) selected_tag_uuids = ListAttribute(StringType()) sharing = StringAttribute(choices=QUESTIONNAIRE_SHARING) state = StringAttribute(choices=QUESTIONNAIRE_STATES) template = ObjectAttribute(TemplateSimple, nullable=True) template_id = StringAttribute(nullable=True) updated_at = DateTimeAttribute() versions = ListAttribute(ObjectType(QuestionnaireVersion)) visibility = StringAttribute(choices=QUESTIONNAIRE_VISIBILITIES) documents = ListOfModelsAttribute(Document, default=[]) def _create(self): raise NotImplementedError('Cannot create questionnaires') def _update(self): raise NotImplementedError('Cannot update questionnaires') def _delete(self): raise NotImplementedError('Cannot delete questionnaires')
class Template(Model): allowed_packages: List[TemplateAllowedPackage] = ListAttribute( ObjectType(TemplateAllowedPackage), ) created_at: datetime = DateTimeAttribute(read_only=True) description: str = StringAttribute() formats: List[TemplateFormat] = ListAttribute(ObjectType(TemplateFormat)) id: str = Alias('uuid') license: str = StringAttribute() metamodel_version: int = IntegerAttribute() name: str = StringAttribute() organization: Optional[OrganizationSimple] = ObjectAttribute( OrganizationSimple, nullable=True, read_only=True, ) organization_id: str = StringAttribute() readme: str = StringAttribute() recommended_package_id: Optional[str] = StringAttribute(nullable=True) registry_link: Optional[str] = StringAttribute( nullable=True, read_only=True, ) remote_latest_version: Optional[str] = StringAttribute( nullable=True, read_only=True, ) state: str = StringAttribute(choices=TEMPLATE_STATES, read_only=True) template_id: str = StringAttribute() usable_packages: List[PackageSimpleDTO] = ListAttribute( ObjectType(PackageSimpleDTO), read_only=True, ) version: str = StringAttribute() versions: List[str] = ListAttribute(StringType(), read_only=True) assets: List[TemplateAsset] = ListOfModelsAttribute(TemplateAsset, default=[]) files: List[TemplateFile] = ListOfModelsAttribute(TemplateFile, default=[]) def _attr_to_str(self, name: str, value: Any) -> str: # Readme is usually quite long, so we display only the beginning if name == 'readme': return truncate_long_string(value, 50) return super()._attr_to_str(name, value) def _create_validate(self): for file in self.files: if file.template_id is not None: raise ValueError(CREATE_VALIDATE_ERR.format('files', 'file')) for asset in self.assets: if asset.template_id is not None: raise ValueError(CREATE_VALIDATE_ERR.format('assets', 'asset')) def _update_validate(self): for file in self.files: if (file.template_id is not None and file.template_id != self.uuid): raise ValueError(UPDATE_VALIDATE_ERR.format('files', 'file')) for asset in self.assets: if (asset.template_id is not None and asset.template_id != self.uuid): raise ValueError(UPDATE_VALIDATE_ERR.format('assets', 'asset')) def _save_template_files(self, diff: SnapshotDiff = SnapshotDiff()): modified_files_uuids = [ file['uuid'] for file in diff.modified.get('files', []) ] for file in self.files: if file.uuid in modified_files_uuids: modified_files_uuids.remove(file.uuid) file.template_id = self.uuid # If it is a new file, it gets created. If it is some old file, # that was just modified, it gets updated. If no there was no # change, `file.save()` won't do anything. file.save() for uuid_to_remove in modified_files_uuids: self._sdk.api.delete_template_file(self.uuid, uuid_to_remove) def _save_asset_files(self, diff: SnapshotDiff = SnapshotDiff()): modified_assets_uuids = [ asset['uuid'] for asset in diff.modified.get('assets', []) ] for asset in self.assets: if asset.uuid in modified_assets_uuids: modified_assets_uuids.remove(asset.uuid) asset.template_id = self.uuid asset.save() for uuid_to_remove in modified_assets_uuids: self._sdk.api.delete_template_asset(self.uuid, uuid_to_remove) def _create(self): self._create_validate() dto = TemplateChangeDTO(**self.attrs()) dto.validate() data = self._sdk.api.post_templates(body=dto.to_json()).json() # We must pop the `files` and `assets`, because they are not yet # created on the server, so there are only empty lists in `data`. data.pop('files', None) data.pop('assets', None) self._update_attrs(**data) self._save_template_files() self._save_asset_files() data = self._sdk.api.get_template(self.id).json() self._update_attrs(**data) def _update(self): self._update_validate() diff = snapshots_diff(self._snapshot, make_snapshot(self)) if 'files' in diff: self._save_template_files(diff) if 'assets' in diff: self._save_asset_files(diff) if len(diff) > 2 or ('files' not in diff and 'assets' not in diff): dto = TemplateChangeDTO(**self.attrs()) dto.validate() data = self._sdk.api.put_template( self.uuid, body=dto.to_json(), ).json() self._update_attrs(**data) def _delete(self): self._sdk.api.delete_template(self.uuid)
class AppConfigAuthExternal(AttributesMixin): services = ListAttribute(ObjectType(AppConfigAuthExternalService))
class AppConfigSubmission(AttributesMixin): enabled = BoolAttribute() services = ListAttribute(ObjectType(AppConfigSubmissionService))
def __init__(self, type_: TypingType[AttributesMixin], **kwargs): super().__init__(ObjectType(type_), **kwargs)
class Answer(AttributesMixin): advice = StringAttribute(nullable=True) follow_up_uuids = ListAttribute(StringType()) label = StringAttribute() metric_measures = ListAttribute(ObjectType(MetricMeasure)) uuid = StringAttribute()
class KnowledgeModelEntities(AttributesMixin): answers = DictAttribute(StringType(), ObjectType(Answer)) chapters = DictAttribute(StringType(), ObjectType(Chapter)) choices = DictAttribute(StringType(), ObjectType(Choice)) experts = DictAttribute(StringType(), ObjectType(Expert)) integrations = DictAttribute(StringType(), ObjectType(Integration)) questions = DictAttribute( StringType(), MappingType( 'question_type', { OPTIONS_QUESTION: ObjectType(OptionsQuestion), MULTI_CHOICE_QUESTION: ObjectType(MultiChoiceQuestion), LIST_QUESTION: ObjectType(ListQuestion), VALUE_QUESTION: ObjectType(ValueQuestion), INTEGRATION_QUESTION: ObjectType(IntegrationQuestion), })) references = DictAttribute( StringType(), MappingType( 'reference_type', { RESOURCE_PAGE_REFERENCE: ObjectType(ResourcePageReference), URL_REFERENCE: ObjectType(URLReference), CROSS_REFERENCE: ObjectType(CrossReference), })) tags = DictAttribute(StringType(), ObjectType(Tag))
class TemplateSimple(AttributesMixin): description = StringAttribute() formats = ListAttribute(ObjectType(TemplateFormat)) id = StringAttribute() name = StringAttribute() version = StringAttribute()
def __init__(self, model_class: Type[Model], **kwargs): super().__init__(ObjectType(model_class), **kwargs)