class TemplateFormat(AttributesMixin): color = StringAttribute() icon = StringAttribute() name = StringAttribute() short_name = StringAttribute() steps = ListAttribute(ObjectType(TemplateFormatStep), nullable=True) uuid = StringAttribute()
class TemplateAsset(Model): content = StringAttribute() content_type = StringAttribute() file_name = StringAttribute() template_id = StringAttribute(immutable=True) def _attr_to_str(self, name: str, value: Any) -> str: if name == 'content': return truncate_long_string(value, 50) return super()._attr_to_str(name, value) def _create(self): dto = TemplateAssetCreateDTO(**self.attrs()) data = self._sdk.api.post_template_assets( dto.template_id, files=dto.files(), ).json() self._update_attrs(**data) def _update(self): raise NotImplementedError('You cannot edit a template asset.') def _delete(self): self._sdk.api.delete_template_asset(self.template_id, self.uuid)
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 UserChangeDTO(AttributesMixin): active: bool = BoolAttribute() affiliation: str = StringAttribute(nullable=True) email: str = StringAttribute() first_name: str = StringAttribute() last_name: str = StringAttribute() role: str = StringAttribute()
class QuestionnaireVersion(AttributesMixin): created_at = DateTimeAttribute() created_by = ObjectAttribute(UserSuggestion) description = StringAttribute(nullable=True) event_uuid = StringAttribute() name = StringAttribute() updated_at = DateTimeAttribute() uuid = StringAttribute()
class AppConfigSubmissionService(AttributesMixin): description = StringAttribute() id = StringAttribute() name = StringAttribute() props = ListAttribute(StringType()) request = ObjectAttribute(AppConfigSubmissionServiceRequest) supported_formats = ListAttribute( ObjectType(AppConfigSubmissionServiceSupportedFormat) )
class Question(AttributesMixin): expert_uuids = ListAttribute(StringType()) question_type = StringAttribute(choices=QUESTION_TYPES) reference_uuids = ListAttribute(StringType()) required_level = IntegerAttribute(nullable=True) tag_uuids = ListAttribute(StringType()) text = StringAttribute(nullable=True) title = StringAttribute() uuid = StringAttribute()
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 HttpClientConfig(ComponentConfig): """ Config for the HTTP client. """ api_url: str = StringAttribute() email: str = StringAttribute() password: str = StringAttribute() enable_ssl: bool = BoolAttribute(default=True) auth_endpoint: str = StringAttribute(default='/tokens') headers: Headers = Attribute(HEADERS_TYPE, default={}) default_timeout: Timeout = Attribute(TIMEOUT_TYPE, default=(6.05, 27))
class TemplateAssetCreateDTO(AttributesMixin): content = StringAttribute() content_type = StringAttribute(nullable=True) file_name = StringAttribute() template_id = StringAttribute(immutable=True) def files(self): file_tuple = (self.file_name, self.content) if self.content_type: file_tuple += (self.content_type, ) return {'file': file_tuple}
class LoggerConfig(ComponentConfig): """ Config for the Logger. """ logger_name: str = StringAttribute(default='dsw_sdk') logger_level: str = Attribute( UnionType(IntegerType(), StringType()), default=logging.WARNING, choices=LOG_LEVELS, ) logger_format: str = StringAttribute( default='[%(asctime)s] - %(name)s | %(levelname)s | %(message)s')
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 Document(Model): created_at = DateTimeAttribute() creator_uuid = StringAttribute(nullable=True) format_uuid = StringAttribute() name = StringAttribute() questionnaire = ObjectAttribute(QuestionnaireDTO, nullable=True) questionnaire_event_uuid = StringAttribute(nullable=True) state = StringAttribute(choices=DOCUMENT_STATES) template = ObjectAttribute(TemplateSimpleDTO) def _create(self): raise NotImplementedError('Cannot create documents') def _update(self): raise NotImplementedError('Cannot update documents') def _delete(self): raise NotImplementedError('Cannot delete documents')
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 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 UserCreateDTO(AttributesMixin): affiliation: str = StringAttribute(nullable=True) # type: ignore email: str = StringAttribute() # type: ignore first_name: str = StringAttribute() # type: ignore last_name: str = StringAttribute() # type: ignore password: str = StringAttribute() # type: ignore role: str = StringAttribute(nullable=True) # type: ignore
class PackageSimpleDTO(AttributesMixin): created_at = DateTimeAttribute() description = StringAttribute() id = StringAttribute() km_id = StringAttribute() name = StringAttribute() organization = ObjectAttribute(OrganizationSimple, nullable=True) organization_id = StringAttribute() state = StringAttribute(choices=PACKAGE_STATES) version = StringAttribute() versions = ListAttribute(StringType())
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 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 AppConfigAuthExternalServiceStyle(AttributesMixin): background = StringAttribute(nullable=True) color = StringAttribute(nullable=True) icon = StringAttribute(nullable=True)
class GroupMembership(AttributesMixin): group_id: str = StringAttribute(immutable=True) type: str = StringAttribute(immutable=True, choices=GROUP_MEMBERSHIP_TYPES)
class UserSuggestion(AttributesMixin): first_name = StringAttribute() gravatar_hash = StringAttribute() image_url = StringAttribute(nullable=True) last_name = StringAttribute() uuid = StringAttribute()
class AppConfigRegistry(AttributesMixin): enabled = BoolAttribute() token = StringAttribute()
class AppConfigAuth(AttributesMixin): default_role = StringAttribute() internal = ObjectAttribute(AppConfigAuthInternal) external = ObjectAttribute(AppConfigAuthExternal)
class AppConfigLookAndFeelCustomMenuLink(AttributesMixin): icon = StringAttribute() new_window = BoolAttribute() title = StringAttribute() url = StringAttribute()
class AppConfigDashboard(AttributesMixin): welcome_info = StringAttribute(nullable=True) welcome_warning = StringAttribute(nullable=True) widgets = ObjectAttribute(AppConfigDashboardWidgets, nullable=True)
class AppConfigPrivacyAndSupport(AttributesMixin): privacy_url = StringAttribute(nullable=True) support_email = StringAttribute(nullable=True) support_repository_name = StringAttribute(nullable=True) support_repository_url = StringAttribute(nullable=True) terms_of_service_url = StringAttribute(nullable=True)
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 AppConfigAuthExternalServiceParameter(AttributesMixin): name = StringAttribute() value = StringAttribute()